依赖注入的模式与类型
- 手动模式: 1.XML,Java注解配置元信息,API配置元信息
- 自动模式: Autowring,即不需要任何配置就能自动注入(根据名字或类型等)
为什么自动模式不被推荐
- 根据名称来自动注入,一旦变量名改了,就无法生效。
- 对于基本类型,比如int,String等,也无法使用自动绑定
Setter方法依赖注入
- XML资源配置元信息,其实是setter注入
- Java注解配置元信息
- API配置元信息:
BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserHolder.class);
// 设置user属性指向superUser这个Bean
definitionBuilder.addPropertyReference("user", "superUser");
BeanDefinition userHolderBeanDefinition = definitionBuilder.getBeanDefinition();
// 将BeanDefinition注入applicationContext中
applicationContext.registerBeanDefinition("userHolder", userHolderBeanDefinition);
// 刷新容器,使得bean被生成
applicationContext.refresh();
构造器注入
- XML资源配置元信息,
- Java注解配置元信息
- API配置元信息
BeanDefinitionBuilder definitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserHolder.class)
// 定义构造器参数
definitionBuilder.addConstructorArgReference("superUser");
return definitionBuilder.getBeanDefinition();
字段注入
字段注入指的是直接对字段操作,而不是对方法或构造器
- Java注解配置元信息:
@Autowried
,@Resource
,@Inject
方法注入
- Java配置元信息:
@Autowired
,@Resource
,@Inject
@Bean
接口回调注入
限定注入
- 使用注解
@Qualifier
限定
1.通过Bean名称限定,在待注入字段上加 @Qualifier('service1')
这个就限定了Bean名称
2.通过分组限定,在@Bean方法上加上@Qualifier,则该Bean被分到了@Qualifier组,如果要扩展组,则自定义注解派生@Qualifier,比如@LoadBalance。被@LoadBalance注解的bean,也能被@Qualifier限定注入,而@Autowired属于没有组,不会注入被分了组的Bean
@Bean
@Qualifier
public User user() {
return new User()
}
@Autowired
// 这里不会注入上面那个bean,因为user Bean已经被分组了
private User user;
延迟依赖注入
- 使用API ObjectFactroy延迟注入
- 使用API ObjectProvider延迟注入(推荐)
@Autowired
private ObjectProvider<User> objectProvider;
依赖处理过程
- 入口-DefaultListableBeanFactory#resolveDependency
- 依赖描述符-DependencyDescriptor
- 自定绑定候选对象处理器-AutowireCandidateResolver
@Autowired
注入
- 元信息解析,AutowiredAnnotationBeanPostProcessor类postProcessMergedBeanDefinition处理元数据
- 依赖查找,AutowiredAnnotationBeanPostProcessor类postProcessProperties进行依赖注入及查找
- 依赖注入(字段、方法)
@Inject
注入
- 如果JSR-330存在于ClassPath中,复用AutowiredAnnotationBeanPostProcessor实现
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
Java通用注解注入原理
- CommonAnnotationBeanPostProcessor处理下面常见的注解
@Resource
@PostConstruct
@PreDestroy
自定义依赖注入注解
- 基于AutowiredAnnotationBeanPostProcessor实现
- 自定义实现, 生命周期处理: InstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor。元数据,InjectedElement,InjectionMetadata用于存储元数据信息。