@Configuration
在介绍Spring核心容器的系列文章中已经多次出现这个注解,从使用的角度来说可以把他理解为XML配置中的<beans>标签,但是两者肯定是不等价的。
在<beans>标签中除了使用<bean>声名Bean以外,还有各种<context>标签来扩展功能,比如<context:component-scan/>、<context:annotation-config />以及<import>等,这些扩展的功能并不是@Configuration注解的参数,而是通过另外一个注解来实现——@ComponentScan、@Import。
@Configuration的基本使用方法已经在纯Java运行与@Bean的“@Bean注解”部分介绍了使用方法,本篇在此基础上进一步进行说明。
@Configuration添加依赖
除了在纯Java运行与@Bean文中介绍的使用方法,我们还可以直接通过使用Java代码来添加依赖关系:
@Configuration
public class MyConfig {
@Bean
public Alice alice() {
//直接使用方法注入数据。
//从表面上看这里调用bob()并没有经过容器处理。而是直接使用了。
return new Alice(bob());
}
@Bean
public Bob bob() {
return new Bob();
}
}
看到这里,思维敏捷的码友通过以下逻辑肯定就发现问题了:
- 通过@Bean注解是向容器添加一个BeanDefinition,
- 在所有的BeanDefinition创建之后容器开始创建Bean之前会执行预设的后置处理器BeanFactoryPostProcessor。
- 最后容器根据BeanDefinition的内容创建Bean。
- return new Alice(bob()); 这段代码中MyConfig::bob方法的调用看起来完全和容器无关,这样就违反了依赖注入的原则!
- 所以是不是Alice类中被注入的Bob实例根本就不是IoC容器中的Bob?
首先可以很负责的告诉码友们Spring并没有限制这个方式去添加Bean,所以例子中Alice类中的Bob实例就是IoC容器中的实例。即使是这样去注入Bean同样实现了依赖注入的功能。至于怎么解决的看完本文自然就能得到答案了。
@Component添加依赖
之前在