大致分析了下Spring的getBean过程,但主要关注doCreateBean。
调用链:preInstantiateSingletons->getBean->doGetBean->getSingleton-> singletonFactory.getObject()->createBean->doCreateBean
图中,需要特别注意getBean
、createBean
、createBeanInstance
、populateBean
、initializeBean
。
由SpringIOC源码学习总结可知,在Spring容器refresh的阶段会调用finishBeanFactoryInitialization->preInstantiateSingletons,然后提前实例化非lazy的单实例。
调用链:createBean->doGetBean->getSingleton
if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {//doGetBeanreturn createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
获得单实例调用链:getSingleton->singletonFactory.getObject()->createBean
singletonObjects
拿到Spring已经缓存的bean实例。singletonFactory.getObject()
->createBean
创建bean。getSingleton源码
synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {//标记为该bean【正在创建】beforeSingletonCreation(beanName);...//创建bean,重点关注singletonObject = singletonFactory.getObject();...//添加到缓存if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}finally {...//去除 【正在创建】 的标记afterSingletonCreation(beanName);}
调用链:createBean->doCreateBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {...RootBeanDefinition mbdToUse = mbd;//从BeanDefinition中取出Class信息Class<?> resolvedClass = resolveBeanClass(mbd, beanName);//为bean设置<bean>标签中的<replaced-method>方法。实现方法重载mbdToUse.prepareMethodOverrides();...//有机会创建代理对象,暂不理会这里Object bean = resolveBeforeInstantiation(beanName, mbdToUse);...//创建bean实例, 重点关注Object beanInstance = doCreateBean(beanName, mbdToUse, args);...return beanInstance;}
FactoryBean#getObject
对应的实例。因此调用该bean的getObject方法返回实例bean,并放入factoryBeanObjectCache
缓存。关于FactoryBean可查看FactoryBean的作用
doCreateBean(beanName, mbdToUse, args)
终于到了今天的主角doCreateBean
。
这里就不贴代码了, 太多了。需要看源码直接看AbstractAutowireCapableBeanFactory#doCreateBean
直接看下流程图:
流程:
createBeanInstance(beanName, mbd, args)
创建一个带有bean实例的BeanWrapper
applyMergedBeanDefinitionPostProcessors
调用BeanPostProcessor收集@Resource、@Autowired、@PreConstruct等注解。addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
。此处是为了解决循环依赖,可查看:spring中怎么解决循环依赖。populateBean
除了处理标签中的property,还利用BeanPostProcessor去处理【2】中收集的@Resource、@Autowired等,完成依赖注入。—CommonAnnotationBeanPostProcessor
以及AutowiredAnnotationBeanPostProcessor
initializeBean
,这里的钩子就比较多:BeanPostProcessor#postProcessBeforeInitialization
InitializeBean.afterPropertiesSet
:如果该bean有实现InitializeBean接口,则调用。<bean>
有配置init-method
则调用。BeanPostProcessor#postProcessAfterInitialization
小结
1.a为常用的Aware接口,b、d为常用的BeanPostProcessor接口,c为常用InitializingBean接口。
2.重点类BeanpostProcessor:CommonAnnotationBeanPostProcessor
、AutowiredAnnotationBeanPostProcessor
createBean 过程总之就是获得BeanDefinition的信息,通过反射创建实例,再注入依赖,然后initializeBean
完成特殊处理,最后放入缓存中。 在整个过程中,留下了许多钩子,我们可以使用Aware接口,BeanPostProcessor去做特殊处理。
最后再放一张详细的图:
联系客服