本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
1、@SpringBootApplication
spring boot 核心注解,加在 Spring boot 主类之上,是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。
(1)@Configuration:允许以 @Bean 注解将对象托管给 spring 容器,即支持将 @Bean 注解的方法返回的对象控制反转。
(2)@EnableAutoConfiguration:启用 Spring boot 自动配置,Spring boot 的一大特色就是无需在 xml 中定义大量配置,开箱即用,原理是使用了将一些常用的配置进行了默认配置,这个注解实现了自动配置这一功能,是 Spring boot 的核心。
(3)@ComponentScan:扫描与 Spring boot 主类被 @Component(@Controller、@Service、@Repository、@RestController) 注解的类,放入 spring boot 容器之中,实现控制反转。由于默认扫描的范围过小,通常会在主类上在声明一个 @ComponentScan,扩大扫描范围。如下:
@SpringBootApplication
@ComponentScan("com.liner")
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
上面的代码主动声明了一个 @ComponentScan 注解,扩大扫描范围至 com.liner 包下所有的类
2、@Component(@Controller、@Service、@Repository、@RestController)
Spring boot 应用面最广,最基础的注解。作用域为:类。会构建该类的对象,放入 spring 容器中,实现控制反转。
(1)@Controller & @RestController:控制层注解。用于接收外部请求的接口类上,提供服务,通常只进行参数校验,不过多处理业务,核心业务由 service 层处理。
【1】@Controller:在早期的应用中,前后端不分离,Spring boot 应用会返回一个视图,而不是 json 之类的纯数据,这个时候会使用 @Controller。后续出现了前后端分离,不再需要返回视图,而是格式化后的纯数据,这时会在接口方法上加入 @ResponseBody 注解。
【2】@RestController:整合了 @Controller 和 @ResponseBody。前后端分离时代产物,使得接口类只返回格式化数据,不返回视图。
(2)@Service:业务层注解,用于处理核心业务逻辑的类上。
(3)@Repository:数据层注解。用于进行数据存入取出的持久层,也就是常说的 Dao 层。Dao 层通常只处理查询、写入数据的简单 sql,不与业务耦合。
3、@Autowired、@Resource、@Qualifier
有了控制反转的注解,自然也得有使用控制反转对象的方法,那就是依赖注入,@Autowired、@Resource、@Qualifier 就是将 Spring 容器中的对象注入到程序中的注解,通常用无属性类中的成员变量之上。
(1)@Autowired:按类型注入,当 Spring 容器中只有该类型的对象时可用。如果 Spring 容器有该类型派生的不同类型对象(子类)时,那么在 spring boot 启动过程中会发生错误。
(2)@Resource:按名称注入,不可指定对象名称,注入的对象与被注解变量名称相同。
(3)@Qualifier:按对象名注入,可通过设置 value 属性决定对象名称。需要与 @Autowired、@Resource 搭配使用。相当于 @Resource 的扩展,更加灵活,可以解除变量名称与对象名必须相同的限制。当与 @Autowired 搭配使用时,必须设置 value;与 @Resource 搭配使用时,可不设置 value,不过通常不会这么用,一个 @Resource 已经满足需求了。用法如下,两个变量实际上都注入了名为 user 的对象
@Autowired
@Qualifier("user")
private User user1;
@Resource
//不指定value时,@Qualifier可以省略,
@Resource
@Qualifier
private User user;
注:@Qualifier 与 @Resource 的不同
【1】来源不同。@Resource 是 jdk 自带的注解,来自 javax.annotation 包,而 @Qualifier 则是来自 springframework,在 org.springframework.beans.factory.annotation 包下面
【2】@Qualifier 功能是 @Resource 的扩展,可通过指定 value 对象确定注入的是哪个对象,不必拘泥于变量名称,更加灵活。
4、@ConfigurationProperties 和 @Value
这两个注解用于读取配置文件中的值来生产对象。@ConfigurationProperties 通常作用于有属性的类上,指定前缀,将 yml 文件中的属性注入到类的成员变量中,并将生成的对象托付给 spring 容器;@Value 用于读取简单类型的配置;
(1)@ConfigurationProperties 用法如下:
【1】首先是 yml 文件配置:
myuser:
id: 1
name: liner
【2】其次是注解的使用:
@ConfigurationProperties(prefix = "myuser")
public class User{
private int id;
private String name;
public int getId() {
return id;
}
public String getName() {
return name;
}
public User() {
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
(2)@Value 用法如下:
1、基础用法
【1】首先是 yml 文件:
test:
num : 1
text: this is text
【2】其次是注入:“${}” 包裹注入
@Value("${test.num}")
private int num;
@Value("${test.text}")
private String text;
注意:
【1】要注入的成员变量必须提供 set 方法,否则无法注入。
【2】定义在 yml 中的 user.name 属性不会生效,因为 user.name 是 Java 的一个系统属性,会获取当前操作系统用户的名称。并注入到被 @ConfigurationProperties(prefix = “user”) 注解的类的 name 属性当中。下图中的 name 属性不会生效
user:
name: test
2、进阶用法,注入数组
在项目中遇到需要使用 yml 文件配置一个 String 数组,使用 @Value 注入。最简单的办法就是将各个字符串使用英文逗号, 隔开,这样就可以注入到一个集合(例如 List)或 String[] 当中,原理是 Spring 会默认按照英文逗号分隔
1、使用, 隔开
(1)yml 配置
arr-test:
strs: str1,str2,str3
(2)注入
@Value("${arr-test.strs}")
private List<String> strs;
@Value("${arr-test.strs}")
private List<String> strList;
2、使用 SpEl 表达式
除了使用英文逗号隔开,由于 @Value 支持 SpEl 表达式,所以可以使用其他符号隔开,并使用表达式分割成数组
(1)yml 配置
arr-test:
list: arr1.arr2.arr3
(2)注入(由于英文逗号. 是特殊字符,需要使用 \ 进行转义)
@Value("#{'${arr-test.list}'.split('\\.')}")
private String[] strArr;
@Value("#{'${arr-test.list}'.split('\\.')}")
private List<String> strList;
3、当配置不存在时,使用默认值
有时配置需要只需要在部分环境下使用,一些环境并不需要该配置,这个时候就需要用到默认值,我们可以使用表达式来赋予一个默认值,代码如下:
@Value("#{'${arr-test.strs:}'.empty ? null : '${arr-test.strs:}'}")
private List<String> strList;
也可以这样写:
@Value("#{'${arr-test.strs:}'.empty ? null : '${arr-test.strs:}'.split(',')}")
private List<String> strList;
此处需要注意前后两个’${arr-test.strs:}'的: 都不能省略,不然在没有配置情况下会注入失败
1、@Configuration 和 @Bean
Spring boot 屏蔽了 xml 文件定义的繁杂,可以使用注解的方式,用代码自由构建 bean,这两个注解为此服务,使用方法如下:
@Configuration
public class BeanConfigTest {
@Bean
public User user() {
User user = new User();
return user;
}
}
注意:上述代码必须在 @ComponentScan 注解定义的扫描包下,否则不会被扫描并生成 bean。如果出现了定义的 bean 注入为 null,那么可以检查下 @ComponentScan 注解的范围。
6、@Scope
Spring boot 中的 bean 有作用域,可以用来指定 bean 的作用域,当使用该注解时,默认的作用域是 singleton(单例,整个程序只生成一个对象)。作用域主要有以下几种:
(1)singleton:单例,整个进程只有一个
(2)prototype :每次获取生成一个对象
(3)request:每次 http 请求生成一个对象,仅服务于当前这次 http 请求。常见的如:HttpServletRequest、HttpServletResponse,HttpServletRequest 可以用来获取 cookie 和 session 等信息;HttpServletResponse 则可以用来获取本次 http 连接的 IO 流等。
(4)session:每个 session 生成一个对象,为当前用户服务,通常用于存储用户信息,如用户的 uuid。
@Scope 使用方法:
(1)作用于类上
/**
* 作用于类上,每次注入变量当中,都会生成一个对象,对于无属性的service层,通常不会这么使用,本次只做示例
*/
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestService {
}
(2)作用于声明的 bean 上
@Configuration
public class BeanConfigTest {
//指定了单例,默认也是单例,每次注入或者获取的对象都是同一个
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public User user() {
User user = new User();
return user;
}
}
prototype 作用域实验:每次获取 / 注入的对象都是新对象
(1)代码:
@Autowired
private TestService testService;
@Autowired
TestService service;
@RequestMapping("/testBean3")
public boolean testBean3() {
return testService == service;
}
(2)结果:
