前文传送门:
本文内容:
- 在IOC中,是如何通过beanDefition创建出一个bean的?
- 各BeanPostProcessor在这过程中扮演的角色,调用时机?
话不多说,直接正题走起,上图!
下面是bean创建过程的大致流程图,本文将以图中顺序进行逐步源码分析,小伙伴亦可与图中流程边对照边品食
原矢量图地址:www.processon.com/view/link/5…
我们知道,在Spring IOC前段部分有注册了一系列的BeanPostProcessor,在Bean的创建过程中,就将要使用到他们了,下面我给大家一一列出
- AutowiredAnnotationBeanPostProcessor:在
new AnnotatedBeanDefinitionReader
时注册 - CommonAnnotationBeanPostProcessor: 在
new AnnotatedBeanDefinitionReader
时注册 - ApplicationContextAwareProcessor: 在
prepareBeanFactory
时注册 - ApplicationListenerDetector: 在
prepareBeanFactory
时注册 - ImportAwareBeanPostProcessor: 在配置类后置处理器调用
postProcessBeanFactory
注册 - BeanPostProcessorChecker:在
registerBeanPostProcessors
时注册
以上就是Spring中内置的所有BeanPostProcessor了
同样,我们先从最开始的入口refresh
开始分析
1 | java复制代码public void refresh(){ |
finishBeanFactoryInitialization
1 | java复制代码protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory){ |
循环我们之前注册的所有beanDefinition,一个个的进行调用getBean注册到容器中
1 | java复制代码public void preInstantiateSingletons(){ |
接下来就是Spring的常规操作,调用do开头的doGetBean
1 | java复制代码public Object getBean(String name) throws BeansException { |
以下为doGetBean
中获取单例bean的逻辑
1 | java复制代码// 转化beanName 如果是以&开头则去除,如果有别名则获取别名 |
getSingleton
1 | java复制代码public Object getSingleton(String beanName) { |
1 | java复制代码protected Object getSingleton(String beanName, boolean allowEarlyReference) { |
getObjectForBeanInstance
1 | java复制代码protected Object getObjectForBeanInstance( |
getObjectFromFactoryBean的代码摘取片段
1 | java复制代码protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess){ |
1 | java复制代码private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName){ |
以上为从缓存中获取到bean,处理FactoryBean的逻辑,接下来我们看看实际创建bean的过程
以下为续接上面doGetBean
中未从缓存中获取到bean的逻辑
1 | java复制代码// 如果有被@DependsOn标记,先创建DependsOn的bean |
getSingleton,此方法为重载方法,与从缓存中获取bean并非同一个
1 | java复制代码public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { |
createBean,终于开始创建bean了~
1 | java复制代码protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){ |
1 | java复制代码protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){ |
你以为这就结束了?
接下来我们就来看看这里后置处理器到底做了什么吧
由于第一次调用并未有任何处理,我们从第二次调用开始分析
createBeanInstance
1 | java复制代码protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){ |
determineConstructorsFromBeanPostProcessors
1 | java复制代码protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) |
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
1 | java复制代码public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName){ |
autowireConstructor 实例化并自动装配,摘取代码片段
1 | java复制代码protected BeanWrapper autowireConstructor( |
1 | java复制代码public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, |
以上便是bean的实例化过程
applyMergedBeanDefinitionPostProcessors
第三次主要是将标识了需要自动装配注解的属性或方法解析出来,包含的注解主要有 @Resource @Autowired @Value @Inject @PostConstruct @PreDestroy
1 | java复制代码protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { |
CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
1 | java复制代码public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { |
InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
1 | java复制代码public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { |
所有的后置处理器的过程是相似的,这里取CommonAnnotationBeanPostProcessor进行分析
我们先来看看寻找元数据的过程
1 | java复制代码private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) { |
buildResourceMetadata
1 | java复制代码private InjectionMetadata buildResourceMetadata(final Class<?> clazz){ |
现在我们再来看看去重处理的过程
1 | java复制代码public void checkConfigMembers(RootBeanDefinition beanDefinition) { |
由于第四次,用于获取早期对象时的处理的调用,在Spring的内置处理器中也没有相应的实现,跳过
这一步和第一步一样,在AOP时将会用到,我们放到下章分析
紧接着就是填充属性的步骤了
populateBean
1 | java复制代码protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { |
autowireByName 和 autowireByType差不多,autowireByType更为复杂一些,这里只分析autowireByType的处理过程
1 | java复制代码protected void autowireByType( |
现在,回到填充属性的过程
该第六次调用后置处理器了,这一次主要对属性和方法进行自动装配
1 | java复制代码// CommonAnnotationBeanPostProcessor 处理@Resouce注解的装配 |
这一步的逻辑也是差不多,由于AutowiredAnnotationBeanPostProcessor复杂一些,我们取AutowiredAnnotationBeanPostProcessor中的逻辑进行分析
1 | java复制代码public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { |
findAutowiringMetadata,看看和第四步有多像吧~
1 | java复制代码private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) { |
自动装配过程
1 | java复制代码public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) { |
1 | java复制代码protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs){ |
1 | java复制代码public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, |
1 | java复制代码public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, |
getBean方法
1 | java复制代码public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) { |
以上就是自动装配的过程,再次回到填充属性的方法,进行小小的收尾
1 | java复制代码// 如果不是xml byName byType 方式,其他方式pvs皆是空值 |
1 | java复制代码protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { |
填充属性过程,over~
初始化过程
initializeBean
1 | java复制代码protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd){ |
以上为初始化中的大概流程,接下来我们一个个分析
首先是invokeAwareMethods
1 | java复制代码private void invokeAwareMethods(String beanName, Object bean) { |
applyBeanPostProcessorsBeforeInitialization
1 | java复制代码public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName){ |
InitDestroyAnnotationBeanPostProcessor
1 | java复制代码public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { |
1 | java复制代码public void invokeInitMethods(Object target, String beanName) throws Throwable { |
1 | java复制代码public void invoke(Object target) throws Throwable { |
ApplicationContextAwareProcessor的过程和invokeAwareMethods的过程类似,这里就不分析了
invokeInitMethods
1 | java复制代码protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd){ |
applyBeanPostProcessorsAfterInitialization
1 | java复制代码public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) |
1 | java复制代码public Object postProcessAfterInitialization(Object bean, String beanName){ |
以上,bean初始化完毕!
伴随着bean初始化完毕,bean就算创建完成了,本文也到此结束啦,有问题的小伙伴欢迎在下方留言哟~
下文预告:Spring源码分析之循环依赖
Spring 源码系列
- Spring源码分析之 IOC 容器预启动流程(已完结)
- Spring源码分析之BeanFactory体系结构(已完结)
- Spring源码分析之BeanFactoryPostProcessor调用过程(已完结)
- Spring源码分析之Bean的创建过程(已完结)
- Spring源码分析之什么是循环依赖及解决方案
- Spring源码分析之AOP从解析到调用
- Spring源码分析之事务管理(上),事物管理是spring作为容器的一个特点,总结一下他的基本实现与原理吧
- Spring源码分析之事务管理(下) ,关于他的底层事物隔离与事物传播原理,重点分析一下
Spring Mvc 源码系列
- SpringMvc体系结构
- SpringMvc源码分析之Handler解析过程
- SpringMvc源码分析之请求链过程
Mybatis 源码系列
暂定
追更,可关注我,近期有时间就文章全写完,分享纯粹为了乐趣,也有一种成就感吧,笔者这篇文章先就到这
本文转载自: 掘金