問題一:何時生成代理對象卷玉,尤其是事務(wù)的代理對象?
在兩個地方可能生成代理對象:
一:InstantiationAwareBeanPostProcessor. postProcessBeforeInstantiation
二:BeanPostProcessor.postProcessAfterInitialization
生成事務(wù)的代理對象執(zhí)行點:
(1)在InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法執(zhí)行
(2)SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference執(zhí)行
問題二:循環(huán)依賴解決?
為何要三級緩存倔既,而不是二級緩存询微?
好處:可擴展葫隙,修改提前暴露的對象
(把 aop 代理對象提前暴露出去株依,如果此時不暴露,循環(huán)依賴時延窜,A 引用的對象不是B 的代理對象)
實現(xiàn):三級緩存中存放的為ObjectFactory對象:singletonFactories恋腕,當(dāng)循環(huán)依賴時獲取緩存對象時,會執(zhí)行工廠方法
ObjectFactory.getObject()-------->
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
進而獲取AOP代理對象逆瑞。
實現(xiàn)過程
SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法作用:
當(dāng)存在循環(huán)依賴時荠藤,通過該回調(diào)方法獲取AOP代理對象
(正常是在InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法中生成代理對象的)伙单。
具體過程
- 實例化對象后會放三級緩存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
注意:放入緩存的是一個ObjectFactory實現(xiàn),只有在循環(huán)依賴時哈肖,第二個對象獲取第一個對象時吻育,會執(zhí)行ObjectFactory.getObject()方法實現(xiàn)(即getEarlyBeanReference)
獲取緩存
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
AbstractAutowireCapableBeanFactory#getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
AbstractAutoProxyCreator是SmartInstantiationAwareBeanPostProcessor的子類,
實現(xiàn)了getEarlyBeanReference用于生成 aop 代理對象的
@Override
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
::wrapIfNecessary方法時生成 AOP代理對象::
- 正常生成 aop 代理對象是在postProcessAfterInitialization方法后淤井,
AbstractAutoProxyCreator#postProcessAfterInitialization實現(xiàn)
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
::postProcessAfterInitialization 中也使用了 wrapIfNecessary::
::不過如果由于在賦值時布疼,為了解決循環(huán)依賴已經(jīng)生成過AOP代理對象,這時不再生成代理::
一文告訴你Spring是如何利用三級緩存巧妙解決Bean的循環(huán)依賴問題的
Spring源碼解析(十二)Spring擴展接口SmartInstantiationAwareBeanPostProcessor
BeanFactory
通過源代碼看看創(chuàng)建一個Bean實例的具體執(zhí)行流程:
[image:A568E489-2D7C-4E9B-9F0B-E1078E700F57-1306-000001E35047C75A/E453601C-514D-4406-9623-ACAB4F899BBD.png]
- bean的實例化通過BeanFactory接口實現(xiàn):DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具體的容器都是實現(xiàn)了BeanFactory币狠,再在其基礎(chǔ)之上附加了其他的功能游两。
- AbstractApplicationContext內(nèi)部使用DefaultListableBeanFactory,且DefaultListableBeanFactory繼承AbstractAutowireCapableBeanFactory漩绵,因此我們此處分析AbstractAutowireCapableBeanFactory即可贱案。
- AbstractAutowireCapableBeanFactory的方法populateBean是主要實現(xiàn),用于給bean實例填充數(shù)據(jù)
Spring創(chuàng)建Bean的流程
首先需要了解是Spring它創(chuàng)建Bean的流程止吐,我把它的大致調(diào)用棧繪圖如下:
對Bean的創(chuàng)建最為核心三個方法解釋如下:
createBeanInstance:實例化宝踪,其實也就是調(diào)用對象的構(gòu)造方法實例化對象
populateBean:填充屬性,這一步主要是對bean的依賴屬性進行注入(@Autowired)
initializeBean:回到一些形如initMethod碍扔、InitializingBean等方法
一文告訴你Spring是如何利用三級緩存巧妙解決Bean的循環(huán)依賴問題
BeanFactory中bean的生命周期
當(dāng)請求getBean時瘩燥,即實例化bean對象。ApplicationContext是在refresh()方法里立即實例化了所有的bean蕴忆。
主要分為三階段
- 實例化颤芬,創(chuàng)建Bean的過程,InstantiationAwareBeanPostProcessor作用于此
- 填充數(shù)據(jù)
- 初始化套鹅,BeanPostProcessor作用于此
階段一:實例化
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()
此方法為核心方法站蝠,用于創(chuàng)建bean實例,填充bean屬性卓鹿,并執(zhí)行后置方法
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
//此處為特殊邏輯菱魔,如果有InstantiationAwareBeanPostProcessor實現(xiàn)生成代理對象,則直接返回吟孙,不會調(diào)下面的方法
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//創(chuàng)建bean實例澜倦,調(diào)用populateBean填充屬性
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
resolveBeforeInstantiation 的功能為:
如果有InstantiationAwareBeanPostProcessor實現(xiàn)的postProcessBeforeInstantiation方法生成代理對象,則直接返回杰妓,不會調(diào)下面的方法
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
注意:實例化之前執(zhí)行InstantiationAwareBeanPostProcessor. postProcessBeforeInstantiation方法藻治,當(dāng)經(jīng)過前置處理之后,返回的結(jié)果若不為空巷挥,那么會直接略過后續(xù)的Bean的創(chuàng)建而直接返回結(jié)果
::原因:resolveBeforeInstantiation只是針對有自定義的targetsource桩卵,因為自定義的targetsource不是spring的bean那么肯定不需要進行后續(xù)的一系列的實例化初始化。所以可以在resolveBeforeInstantiation直接進行proxy::
Spring源碼解析(十一)Spring擴展接口InstantiationAwareBeanPostProcessor解析
Spring之InstantiationAwareBeanPostProcessor接口介紹 - 云+社區(qū) - 騰訊云
Spring Aop之Target Source詳解Java愛寶貝丶的博客-CSDN博客
階段二:填充實例-populateBean實現(xiàn)
位于:AbstractAutowireCapableBeanFactory#populateBean
主要功能:
- 把Autowired注解的屬性注入到實例中
- 執(zhí)行實現(xiàn)了InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法修改實例
執(zhí)行流程。如下:
- 獲取屬性列表 pvs
- 在屬性被填充到 bean 前雏节,應(yīng)用后置處理自定義屬性填充
- 根據(jù)名稱或類型解析相關(guān)依賴
- 再次應(yīng)用后置處理胜嗓,用于動態(tài)修改屬性列表 pvs 的內(nèi)容
- 將屬性應(yīng)用到 bean 對象中
注意第3步,也就是根據(jù)名稱或類型解析相關(guān)依賴(autowire)钩乍。該邏輯只會解析依賴辞州,并不會將解析出的依賴立即注入到 bean 對象中。所有的屬性值是在 applyPropertyValues 方法中統(tǒng)一被注入到 bean 對象中的寥粹。
Spring IOC 容器源碼分析 - 填充屬性到 bean 原始對象_慕課手記
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
// 獲取屬性列表
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
boolean continueWithPropertyPopulation = true;
/*
* 在屬性被填充前变过,給 InstantiationAwareBeanPostProcessor 類型的后置處理器一個修改
* bean 狀態(tài)的機會。關(guān)于這段后置引用排作,官方的解釋是:讓用戶可以自定義屬性注入牵啦。比如用戶實現(xiàn)一
* 個 InstantiationAwareBeanPostProcessor 類型的后置處理器,并通過
* postProcessAfterInstantiation 方法向 bean 的成員變量注入自定義的信息妄痪。當(dāng)然衫生,如果無
* 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建議大家直接實現(xiàn)
* InstantiationAwareBeanPostProcessor 接口,如果想實現(xiàn)這種類型的后置處理器帕膜,更建議
* 通過繼承 InstantiationAwareBeanPostProcessorAdapter 抽象類實現(xiàn)自定義后置處理器。
*/
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
/*
* 如果上面設(shè)置 continueWithPropertyPopulation = false,表明用戶可能已經(jīng)自己填充了
* bean 的屬性瞒大,不需要 Spring 幫忙填充了。此時直接返回即可
*/
if (!continueWithPropertyPopulation) {
return;
}
// 根據(jù)名稱或類型注入依賴
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 通過屬性名稱注入依賴
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 通過屬性類型注入依賴
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
/*
* 這里又是一種后置處理背率,用于在 Spring 填充屬性到 bean 對象前划滋,對屬性的值進行相應(yīng)的處理,
* 比如可以修改某些屬性的值。這時注入到 bean 中的值就不是配置文件中的內(nèi)容了,
* 而是經(jīng)過后置處理器修改后的內(nèi)容
*/
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 對屬性進行后置處理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 應(yīng)用屬性值到 bean 對象中
applyPropertyValues(beanName, mbd, bw, pvs);
階段三:初始化實例
初始化過程主要包含以下幾個過程:
- 執(zhí)行BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 接口實現(xiàn)
- 執(zhí)行BeanPostProcessor.postProcessAfterInitialization:
- 執(zhí)行InitializingBean接口的中afterPropertiesSet()方法(如果該實例實現(xiàn))
- 執(zhí)行實例init method
- 執(zhí)行BeanPostProcessor.postProcessAfterInitialization
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}