Spring注解是如何生效的?
现在大部分开发已经采用Spring Boot了,少了很多配置文件,方便了许多。以前在使用注解,比如@Autowired、@Resource 或者事务相关的一些注解时,我们会首先在配置文件里面加入这样的配置:
context:component-scan
context:annotation-config
tx:annotation-driven
这样就能告诉Spring容器在启动的时候,把相应的后处理器(BeanPostProcessor)初始化,交给Spring容器来管理,然后通过这些后处理器 去实现 各种注解(的功能),比如实现:@Autowired 默认 按类型注入属性 。具体来说,@Autowired 是Spring框架提供的注解,它是由AutowiredAnnotationBeanPostProcessor 后处理器实现的;@Resource 是JDK里面提供的注解,它由CommonAnnotationBeanPostProcessor实现注入的功能。
那使用了Spring Boot之后,几乎已经看不到上述配置了,简单来说:Spring Boot应用程序在启动的时候,默认加载了一批BeanPostProcessor,这样就可以实现这些注解的功能了。这是怎么做到的呢?
我们知道,Spring Boot应用程序会在Application启动类中标上 @SpringBootApplication 注解。这个注解包含了三个子注解:
- SpringBootConfiguration 将Application启动类作为Bean类注入到Spring容器中
- EnableAutoConfiguration 实现自动配置功能
- ComponentScan 实现自动扫描的功能,具体来说:就是告诉Spring容器注册"一些"Bean后处理器,从而能够支持各种注解。
比如说,要想让@Autowired生效,Spring容器必须加载了AutowiredAnnotationBeanPostProcessor 后处理器,看这个类的源码注释:
A default AutowiredAnnotationBeanPostProcessor will be registered by the "context:annotation-config" and "context:component-scan" XML tags.
因此,只要我们在XML配置文件里面配置了 context:component-scan
,AutowiredAnnotationBeanPostProcessor 就能被注册到Spring容器中。而使用Spring Boot之后,由@SpringBootApplication注解下面的@ComponentScan 完成了同样的功能。这就是不需要我们自己在XML配置文件里面写一行 context:component-scan
配置的原因。
类似地:CommonAnnotationBeanPostProcessor 实现了 @Resource 注解的功能,看看它的类源码注释可知:它负责实现@PostConstruct、@PreDestroy、@Resource等注解,配置了 @ComponentScan 就能将它注册到Spring容器中。
最后再来说说开启事务的注解@EnableTransactionManagement:
当我们在Application启动类 上标注 @EnableTransactionManagement 时,就表示开启事务,它等价于XML配置方式 tx:annotation-driven
。