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,扩大扫描范围。如下:
java
@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的对象
java
@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文件配置:
java
myuser:
id: 1
name: liner
【2】其次是注解的使用:
java
@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】首先是yml文件:
java
test:
num : 1
text: this is text
【2】其次是注入:"${}" 包裹注入
java
@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属性不会生效
java
user:
name: test
1、@Configuration和@Bean
Spring boot 屏蔽了xml文件定义的繁杂,可以使用注解的方式,用代码自由构建bean,这两个注解为此服务,使用方法如下:
java
@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)作用于类上
java
/**
* 作用于类上,每次注入变量当中,都会生成一个对象,对于无属性的service层,通常不会这么使用,本次只做示例
*/
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestService {
}
(2)作用于声明的bean上
java
@Configuration
public class BeanConfigTest {
//指定了单例,默认也是单例,每次注入或者获取的对象都是同一个
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public User user() {
User user = new User();
return user;
}
}
prototype作用域实验:每次获取/注入的对象都是新对象
(1)代码:
java
@Autowired
private TestService testService;
@Autowired
TestService service;
@RequestMapping("/testBean3")
public boolean testBean3() {
return testService == service;
}
(2)结果: