前置知识
1 入口 DefaultListableBeanFactory#resolveDependency
2 每个依赖都有对应的DependencyDescriptor
3 自定绑定候选对象处理器AutowireCapableBeanFactory
注入处理
我们可以看到AutowireCapableBeanFactory中有两个方法:
第一个是单个注入:
java
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
还有一个是Set集合注入:
java
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
java
public class AnnotationDependencyInjectResolutionDemo {
@Autowired
private Person person;
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(AnnotationDependencyInjectResolutionDemo.class);
context.refresh();
QualifierAnnotationDependencyInjectDemo bean = context.getBean(QualifierAnnotationDependencyInjectDemo.class);
}
}
我们直接断点看一下DependencyDescriptor 里面的信息:
DependencyDescriptor 描述了我们要注入的目标的一些信息,申明类,字段名称,是否必须对应的就是Autowired的知否必须,eager是否是肌饿模式(实时注入),一般不用懒加载都是肌饿的。
注入过程
1 普通的字段注入
java
@Autowired
private Person person;
-
字段注入前面的判断都会跳过进入到下面这个方法
-
让后进入的下一个核心方法
进入这个方法:
候选的Bean是通过上面这个方法找到的,并且返回的时候将Bean对象放入到Map中。
然后我们如果我们多个bean,determineAutowireCandidate这个方法会决定一个Bean,决定的方式为如果使用了Primary就注入PrimaryBean否则Ordered根据这个接口定义的优先级来寻找,数字越低优先级越高:
2 集合注入
java
@Autowired
private Collection<Person> personGroupAll;
集合注入核心逻辑会走到下面这个方法,这个方法返回的时候multipleBeans已经不为空了这个这个直接返回。
为什么上面可以直接返回呢,因为在resolveMultipleBeans方法中,判断了注入的类型如果是集合类型,也是走的一样的逻辑findAutowireCandidates找到候选的Bean进行返回。
3 懒加载
java
@Autowired
@Lazy
private Person person;
在懒注入的时候我们在这个方法已经有值了,所以逻辑在这一步就结束了,返回的是一个代理对象。
这个对象是cglib提升后的对象:
4 Optional注入
java
@Autowired
private Optional<Person> person;
核心逻辑是走下面
其实里面的逻辑是一样的,只是最后封装为Optional:
@Autowired的原理
会先调用AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
然后调用这个方法:
最后通过反射进行注入: