BeanDefinitionRegistryPostProcessor调用分为三部分:
1.调用实现了PriorityOrdered 排序接口
2.调用实现了Ordered 排序接口
3.没有实现接口的调用
这个接口的理解:获取BeanDefinitionRegistry 对象,获取到这个对象就可以获取这个对象中注册的
所有BeanDefinition 对象,所以我们知道了,我们拥有这个对象就可以完成里面所有BeanDefinition 对
象的修改我新增操作
BeanPostProcessor 的注册
入口:AbstractApplicationContext.refresh()方法中调用registerBeanPostProcessors(beanFactory);把实现了BeanPostProcessor接口的类实例化,并且加入到BeanFactory中
- 拿到工程里面所有实现了BeanPostProcessor接口的类,获取到BeanDefinition的名称
- 拿到BeanFactory 中所有注册的BeanDefinition 对象的名称beanName
然后判断是否实现了PriorityOrdered 排序接口,Ordered 排序接口,getBean 是将
该ppName 对应的BeanDefinition 对象实例化。 - registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); 注入到BeanFactory中,BeanFactory是一个list接收。
getSingleton 方法
把beanName 添加到singletonsCurrentlyInCreation Set 容器中,在这个集合里
面的bean 都是正在实例化的bean,就是实例化还没做完的BeanNamegetObject 调用完后,就代表着Bean 实例化已经完成了,这时候就需要
1、singletonsCurrentlyInCreation 把beanName 从这个集合中删除
2、addSingleton,把bean 缓存到一级缓存中
createBean 方法
createBean 方法
AbstractBeanFactory.doGetBean 方法中
这个方法是bean 实例化核心方法
实例化方法,把bean 实例化,并且包装成BeanWrapper
1、点进这个方法里面
spring 会扫描有@bean 注解的方法,然后把方法名称设置到BeanDefinition 的factoryMethod
属性中,接下来就会调到上面截图中的方法实现@Bean 方法的调用
2、有参构造函数的时候
determineConstructorsFromBeanPostProcessors
这个方法是BeanPostProcessor 接口类的首次应用,最终会掉到
AutowiredAnnotationBeanPostProcessor 类的方法,在方法中会扫描有注解的构造函数然后完
成装配过程。然后把所有@Autowired 注解的构造函数返回。
3、无参构造函数的实例化
4、类中注解的收集
@Autowired 或者@Resource 注解
注解的收集:
也是通过BeanPostProcessor 接口类型实例来挨个处理的。
A、首先是
CommonAnnotationBeanPostProcessor 类,这个类完成了@Resource 注解的属性或
者方法的收集
这个类还对@PostConstruct 和@PreDestory 支持
收集过程
1、看缓存里面有没有InjectionMetadata 对象
2、从类中获取所有Field 对象,循环field 对象,判断field 有没有@Resource 注解,
如果有注解封装成ResourceElement 对象
3、从类中获取所有Method 对象,循环Method 对象,判断Method 有没有@Resource
注解,如果有注解封装成ResourceElement 对象
4、最终把两个field 和Method 封装的对象集合封装到InjectionMetadata 对象中
B、然后是
AutowiredAnnotationBeanPostProcessor 类,对@Autowired 注解的属性和方法
的收集。收集过程基本上跟@Resource 注解的收集差不多。5、IOC\DI 依赖注入
这里又是一个BeanPostProcessor 类型接口的运用,前面我们讲到了
@Resource@Autowired 注解的收集,那么这个方法就是根据收集到的注解进行反射调
用。
循环收集到的metaData 中的list 对象,然后挨个调用里面的InjectedElement 的
inject 方法完成依赖注入。
其中value 值的获取,如果依赖的属性是一个引用类型必定会触发该属性的
BeanFactory.getBean 操作,从而从spring 容器中获取到对应的实例。方法的依赖注
入类似这里就不再赘述。
上述是对注解@Resource 和@Autowired 的依赖注入的实现逻辑,xml 配置的依赖注入
比如在bean 标签中配置了:
标签的依赖注入是这个逻辑:
简述:
收集:首先走到beanProcessors,走到CommentAnntationBeanProcessor,拿到正在实例化bean的反射对象,再拿到对象里面所有属性或者方法,然后循环对象里面所有属性和方法,根据属性值判断这个属性上是否有注解,如果有注解包装成InjectedElement对象,最终装入到集合,再把这个集合包装成metadata对象
依赖注入:
IOC依赖注入的时候,就会找对应的metadata,触发getBean操作,通过beanName找到value值,就拿到了对应的student的类的实例,反射把拿到的值复制到属性中