finishBeanFactoryInitialization 源码解析
Instantiate all remaining (non-lazy-init) singletons.
初始化剩下非懒加载的实例对象
finishBeanFactoryInitialization方法第918行,beanFactory.preInstantiateSingletons();
preInstantiateSingletons方法,遍历beanDefinitionNames,通过mergedBeanDefinitions来获取每一个RootBeanDefinition,并判断他是否是factorybean,如果不是,调用getBean()方法。如果是,看到后面的FactoryBean部分
doGetBean方法
第252行,transformedBeanName(name),用于返回真实beanName,如果是beanName以&开头(表示factoryBean),去掉&并返回。通过Map<String, String> aliasMap来获取该beanName是否为别名,如果key有值,返回value
第256行,getSingleton(beanName),通过singletonObjects来获取之前是否已经注入到IOC中
Eagerly check singleton cache for manually registered singletons.
在这里面做了三级缓存,也是spring解决循环依赖的地方,在后面分析
这里做调试的类没有进行过初始化,singletonObjects返回null
AbstractBeanFactory第300行,typeCheckOnly一般都为false(用于类型检查实例是否获得,而不是实际使用)
进入markBeanAsCreated方法
判断alreadyCreated(已标记为创建)是否包含beanName,这里通过双重校验锁,如果不包含,将beanName添加到alreadyCreated
clearMergedBeanDefinition方法,将bd的stale设置为true,并从mergedBeanDefinitionHolders移除beanName
AbstractBeanFactory第309行,getMergedLocalBeanDefinition方法
进入getMergedLocalBeanDefinition方法
从mergedBeanDefinitions取出beanName对应的RootBeanDefinition
回到AbstractBeanFactory,判断类是否有@DependsOn注解
第332行,开始创建对象实例
getSingleton.getObject()
进入getSingleton方法
通过双重校验再次判断singletonObjects是否存在beanName
第234行,开始调用ObjectFactory(类似Supplier)的getObject方法
第514行,resolveBeanClass,解析beanClass,如果是对象被代理,返回代理对象的class
第531行,resolveBeforeInstantiation,如果有自定义InstantiationAwareBeanPostProcessor实现,调用postProcessBeforeInstantiation(实例化之前执行)。可以实例化自定义bean,但是这个回调会在所有bean实例化的时候都执行。非自定义的类也会在这里实例化,会有不可预估的风险,如果方法返回的不为null,表示已经实例化,直接返回这个bean作为创建的单例对象,并注册到IOC容器。
Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
第542行,doCreateBean,正式开始实例化bean
doCreateBean
第582行,进入createBeanInstance
createBeanInstance
determineConstructorsFromBeanPostProcessors,在这里回调SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法,可以用来设置类的自定义构造器
instantiateBean方法,通过默认无参构造来实例化bean
进入instantiateBean方法,第1326行。beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
通过实例化策略执行器开始实例化bean,主要还是通过构造器实例化,过程略。
返回实例对象后,封装成BeanWrapper并返回
applyMergedBeanDefinitionPostProcessors
实例化bean之后,第594行,applyMergedBeanDefinitionPostProcessors方法。会在这里回调MergedBeanDefinitionPostProcessor接口postProcessMergedBeanDefinition方法
populateBean
InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation回调
进入populateBean方法,第1399行,回调InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation。用于自定义判断bean与beanName是否满足相同预期结果
InstantiationAwareBeanPostProcessor的postProcessProperties回调
第1431行,回调InstantiationAwareBeanPostProcessor接口的postProcessProperties方法
AutowiredAnnotationBeanPostProcessor(@Autowire依赖处理)
spring的实现类AutowiredAnnotationBeanPostProcessor,这里会根据进行@Autowire注解的依赖注入,会实例化依赖的类
CommonAnnotationBeanPostProcessor(@Resource依赖处理)
或者如果使用的@Resource注解,会通过CommonAnnotationBeanPostProcessor类来实例化类
以上两种注入方式,都会通过beanFactory.getBean(beanName);来实例化依赖类,如果依赖为接口,需要找实现接口的类并实例化,如果是类直接进行实例化
initializeBean
进入initializeBean,第1791行,invokeAwareMethods
invokeAwareMethods
判断bean是否实现Aware,如果当前对象是cglib生成的代理对象,默认实现EnhancedConfiguration接口,该接口继承了BeanFactoryAware
把beanFactory设置到bean中
BeanPostProcessor的postProcessBeforeInitialization回调
CommonAnnotationBeanPostProcessor
由父类InitDestroyAnnotationBeanPostProcessor执行postProcessBeforeInitialization,会触发bean的@PostConstruct注解方法(充当init-method)
ConfigurationPropertiesBindingPostProcessor回调
ConfigurationPropertiesBindingPostProcessor的postProcessBeforeInitialization,会执行@ConfigurationProperties的自定绑定model字段逻辑。
判断类上是否有@ConfigurationProperties,并创建ConfigurationPropertiesBean返回
获取待绑定的字段,从PropertySource中寻找该字段对应的值(PropertySource值在之前已经缓存)
最终通过JavaBeanBinder的setValue方法,来为字段赋值
invokeInitMethods
InitializingBean的afterPropertiesSet回调
@Bean(initMethod = “doInit”)回调doInit
如果对象有初始化方法(在其他配置类中定义的@Bean(initMethod = “doInit”)),会进行调用
BeanPostProcessor的postProcessAfterInitialization回调
AnnotationAwareAspectJAutoProxyCreator(创建AOP代理)
创建AOP代理,详细分析看下面AOP章节
getSingleton
上面已经将对象实例化。
第633行,getSingleton方法。
registerDisposableBeanIfNecessary
第661行,registerDisposableBeanIfNecessary方法。
待补充
addSingleton(beanName, singletonObject)
注册单例对象到IOC容器
SmartInitializingSingleton回调
遍历所有容器单例对象,判断是否实现SmartInitializingSingleton,如果实现会调用afterSingletonsInstantiated方法
至此finishBeanFactoryInitialization结束
循环依赖的处理
前提:开启允许循环依赖,springboot 2.6 之后就默认关闭了。
A(cicA)与B(cicB)相互依赖,A先进行初始化
-
A完成bean实例创建
-
判断是否开启了循环依赖,并添加A的bean实例工厂到beanFactory的singletonFactories中(作为第三级缓存)
-
在populateBean方法中,回调InstantiationAwareBeanPostProcessor的postProcessProperties方法。这里我们需要关注AutowiredAnnotationBeanPostProcessor类。执行依赖注入
通过A上被@Autowire修饰的成员变量,获取到待注入的类(这里的cicB是与当前类互为循环依赖的),封装成InjectedElement
遍历这两个InjectedElement,依次进行解析,并调用beanFactory.getBean(beanName)。这里的bean是cicB
-
B完成bean实例创建,和A的第1步一样
-
添加B的bean实例工厂到beanFactory的singletonFactories中,和A的第2步一样
-
依然通过AutowiredAnnotationBeanPostProcessor的postProcessProperties方法,获取B下的被@Autowire修饰的成员变量,来执行依赖注入
和A的第3步一样,调用beanFactory.getBean(beanName)。这里的bean是cicA
来到doGetBean的getSingleton(beanName)方法,从这里尝试获取A的对象
a. 首先从一级缓存singletonObjects获取bean,因为A对象只是实例化,还没有初始化,因此还没有注入到singletonObjects中
b.一级缓存中获取不到bean,从二级缓存earlySingletonObjects获取,此时二级缓存也没有A的对象
c. 这里通过双重校验锁再次确保一、二级缓存都不存在bean。从三级缓存singletonFactories中获取到对象的ObjectFactory,通过执行ObjectFactory.getObject方法。调用如下的函数式接口,beanName为cicA,bean为实例化之后的cicA对象,返回该对象
这里会调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
返回cicA对象,将对象放入二级缓存earlySingletonObjects中
获取到cicA之后,通过Field将cicA设置到cicB的字段中
-
cicB完成初始化,注册到一级缓存,从二、三级缓存删除
-
返回cicB,通过Field将cicB设置到cicA的字段中
-
cicA完成初始化,注册到一级缓存,从二、三级缓存删除
总结
FactoryBean
用于创建比较复杂的bean
比如从配置文件中获取配置,通过不同值来生成不同bean
自定义FactoryBean
package org.hopehomi.boot.model.factorybean;import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;/*** @author Ledison* @date 2023/3/19*/
@Component
@Slf4j
@Data
public class MyFactoryBean implements SmartFactoryBean<Human>, InitializingBean, DisposableBean {private Human human;@Autowiredprivate Environment environment;public MyFactoryBean() {System.out.println("MyFactoryBean construct");}@Overridepublic boolean isEagerInit() {return true;}@Overridepublic void afterPropertiesSet() throws Exception {String sex = environment.getProperty("sex");if (sex.equals("1")) {human = new Man();} else {human = new Woman();}}@Overridepublic Human getObject() throws Exception {return human;}@Overridepublic Class<?> getObjectType() {return Human.class;}@Overridepublic boolean isSingleton() {return true;}@Overridepublic void destroy() throws Exception {System.out.println("MyFactoryBean (DisposableBean) destroy");}}
在使用中根据beanFactory的beanName来获取对象,取到的是getObject的对象。和根据bean类获取到的对象相同
如果需要获取原始Factorybean对象,需要在Factorybean前加&
源码分析
preInstantiateSingletons - getBean
preInstantiateSingletons方法,判断bean为FactoryBean
getBean
过程与前面非FactoryBean大致相同,直接来到docreateBean
doCreateBean
这里会从factoryBeanInstanceCache中获取beanName的BeanWrapper。
这个缓存是在registerBeanPostProcessors(beanFactory)的过程中就实例化了FactoryBean对象并添加到缓存中,源码略
BeanWrapper不为null,就不会在这进行实例化,后面的逻辑也和普通bean相同,依赖注入、调用初始化方法
preInstantiateSingletons - isEagerInit
获取到FactoryBean的实例
如果FactoryBean实现了SmartFactoryBean且isEagerInit为true,会在这里更早进行初始化代理对象。
注意这里的beanName前面没有加&
getObjectForBeanInstance
先判断是否name以&开头,如果以&开头,表示是FactoryBean的本体name
那么直接返回本体对象
如果不是以&开头,从IOC容器获取到了FactoryBean的实例,调用getObjectFromFactoryBean方法来获取代理对象
getObjectFromFactoryBean
doGetObjectFromFactoryBean
这里调用FactoryBean的getObject方法,用来返回自定义代理实例
将代理对象放入factoryBeanObjectCache。下次再执行getBean会直接从factoryBeanObjectCache中返回对象。
AOP
自定义AOP配置
拦截以R作为返回值且类上包含@Controller、@RestController
被代理对象
源码分析
AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization
initializeBean时,BeanPostProcessor的postProcessAfterInitialization回调。由AnnotationAwareAspectJAutoProxyCreator类执行
先从二级缓存中获取bean,如果存在bean直接返回(已经做了代理,这段逻辑在下面加载时机二进行说明)
wrapIfNecessary
Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
如果满足被代理条件,创建对象代理
shouldSkip
findCandidateAdvisors => findAdvisorBeans
- 获取继承Advisor接口的类,这里返回BeanFactoryTransactionAttributeSourceAdvisor
- 获取包含@Aspect的类
下图返回我们自定义的AOP配置
getAdvicesAndAdvisorsForBean
Create proxy if we have advice.
如果bean有advice则创建代理
findEligibleAdvisors
当前bean符合被代理条件
作为结果返回
createProxy
proxyFactory.getProxy
createAopProxy
- 这里采用工厂设计模式,先获取AOP工厂,默认为DefaultAopProxyFactory
- 创建AOP代理
如果当前是接口、或者实现了Proxy类、或者是Lambda类,返回JdkDynamicAopProxy
否则返回ObjenesisCglibAopProxy
实现接口一定是使用JDK动态代理吗?不是
这里我的类是TestImportController,并且实现了BaseTestImportController接口,按理来说应该通过jdk的动态代理,但是跟源码的时候发现使用的是cglib代理,我问了chatgpt,原因是出在我的Aspect类,以下是回答
我根据上面的回答,又创建了一个Aspect
controller使用注解
但是在创建代理的时候依然是走的cglib
我又问了chatgpt
但是我设置了@EnableAspectJAutoProxy(proxyTargetClass = false)还是不行
看来只能手动设置Proxy来支持jdk动态代理
getProxy
上面通过工厂返回了对应的AopProxy实现,接下来就是根据不同的方式创建代理对象
这里以cglib举例,下面是生成的代理对象
加载时机一:initializeBean时候,判断bean是否需要被代理
上述的源码分析,initializeBean的时候
加载时机二:循环依赖时提前创建代理
流程
前提:CicA和CicB为循环依赖,且两个类都会被代理
- CicA创建实例
- CicA执行populateBean来注入属性,发现有cicB
- CicB创建实例
- CicB执行populateBean来注入属性,发现有cicA
- CicB通过三级缓存获取到实例化的cicA,然后对cicA提前代理创建
- 返回代理的cicA对象,通过Field赋值属性完成CicB属性注入
- CicB执行initializeBean完成自身代理对象创建
源码
进入wrapIfNecessary方法,与普通代理逻辑一样,返回代理对象。
将代理对象加入到二级缓存
为什么循环需要提前创建代理
如果不提前创建代理,这时候依赖的类为普通bean,当该bean进行initializeBean创建代理之后,会出现依赖类与代理类不一致的情况,所以需要二级缓存来提前创建代理