文章目录
目录
一、AutowiredAnnotationBeanPostProcessor
二、MergedBeanDefinitionPostProcessor执行
2.1 postProcessMergedBeanDefinition方法执行
前言
SpringBoot的两大特性,控制反转(IOC)和AOP,上一篇文章已经分析过了IOC的原理。下面就来分析分析IOC的原理。控制反转,顾名思义就是将注入类的控制权限交由Spring容器管理。被注入类并不知道将要注入的具体类是哪个,具体注入哪个类将由Spring控制。这样就可以通过注入接口类型类的方式去注入类,利用类的多态特性,可以根据业务的不同去指定不同的实现类去执行逻辑。
控制反转最重要的就是类的创建和注入,类的注入方式有多个,例如@Autowried、@Resource、@Qualifiler、构造方法注入、getter/setter方法注入等。本篇文章先分析@Autowried注解注入的方式去说明IOC的注入,同时通过分析源码的方式也可以近一步分析为什么不推荐使用注解注入的方式。
一、AutowiredAnnotationBeanPostProcessor
这里直接公布答案,SpringBoot通过AutowiredAnnotationBeanPostProcessor去处理和解析@Autowried注解。看到名字就知道,这又是SpringBoot的一个扩展点
该类实现了MergedBeanDefinitionPostProcessor和 InstantiationAwareBeanPostProcessor,这两个也是SpringBoot的扩展点,@Autowried就是通过这两个扩展点的方法来实现的。下面就通过分析这两个扩展点中的方法的执行时间,以及方法中的逻辑去分析@Autowried是如何进行依赖注入的。
二、MergedBeanDefinitionPostProcessor执行
2.1 postProcessMergedBeanDefinition方法执行
SpringBoot中Bean的创建过程这里就不多赘述了,直接进入doCreateBean方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
......
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
......
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
......
}
可以看到这里执行了applyMergedBeanDefinitionPostProcessors方法
这个方法是执行所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法。关键点来了,这里就可以看MergedBeanDefinitionPostProcessor的该方法的逻辑了。
看方法名就能联想到,这个方法是查找到Autowried的原始参数,进入方法来看一下具体的逻辑。
这里面主要是创建InjectionMetadata对象 ,这个类应该就是需要注入的类的一些信息。
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
......
// 通过反射获取所有字段,并且处理字段上面的@Autowried注解,并放入currElements中
ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
MergedAnnotation<?> ann = this.findAutowiredAnnotation(field);
......
});
// // 通过反射获取所有方法,并且处理字段上面的@Autowried注解,并放入currElements中
ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
......
});
}
最终会将生成的InjectionMetadata对象放入injectionMetadataCache缓存中。
2.2 postProcessProperties方法执行
postProcessProperties方法是属于扩展点InstantiationAwareBeanPostProcessor中的方法,他的执行时机就是在Bean实例化之后,给Bean中的元素进行赋值。具体是在populateBean方法中执行的。
下面就来看一下AutowiredAnnotationBeanPostProcessor类中该方法的具体逻辑
找到上一步中创建的InjectionMetadata对象,然后调用其中的inject方法。
通过反射,给字段或者方法赋值,这样@Autowried就注入成功了。具体的逻辑在AutowiredFieldElement中实现的。
总结
上面就是SpringBoot中@AutoWried注入的原理,刚开始看源码的时候,没注意InjectedElement是一个抽象类,它获取bean的方法返回了一个null,当时就很疑惑,为什么这里是null,难道是因为这个阶段是实例化阶段,还未给字段赋值?后面断点看了一下,发现是通过AutowiredFieldElement这个去实现的逻辑