问题一:何时生成代理对象,尤其是事务的代理对象?
在两个地方可能生成代理对象:
一:InstantiationAwareBeanPostProcessor. postProcessBeforeInstantiation
二:BeanPostProcessor.postProcessAfterInitialization
生成事务的代理对象执行点:
(1)在InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法执行
(2)SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference执行
问题二:循环依赖解决?
为何要三级缓存,而不是二级缓存?
好处:可扩展,修改提前暴露的对象
(把 aop 代理对象提前暴露出去,如果此时不暴露,循环依赖时,A 引用的对象不是B 的代理对象)
实现:三级缓存中存放的为ObjectFactory对象:singletonFactories,当循环依赖时获取缓存对象时,会执行工厂方法
ObjectFactory.getObject()-------->
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
进而获取AOP代理对象。
实现过程
SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法作用:
当存在循环依赖时,通过该回调方法获取AOP代理对象
(正常是在InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization方法中生成代理对象的)。
具体过程
- 实例化对象后会放三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
注意:放入缓存的是一个ObjectFactory实现,只有在循环依赖时,第二个对象获取第一个对象时,会执行ObjectFactory.getObject()方法实现(即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的子类,
实现了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实现
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::
::不过如果由于在赋值时,为了解决循环依赖已经生成过AOP代理对象,这时不再生成代理::
一文告诉你Spring是如何利用三级缓存巧妙解决Bean的循环依赖问题的
Spring源码解析(十二)Spring扩展接口SmartInstantiationAwareBeanPostProcessor
BeanFactory
通过源代码看看创建一个Bean实例的具体执行流程:
[image:A568E489-2D7C-4E9B-9F0B-E1078E700F57-1306-000001E35047C75A/E453601C-514D-4406-9623-ACAB4F899BBD.png]
- bean的实例化通过BeanFactory接口实现:DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。
- AbstractApplicationContext内部使用DefaultListableBeanFactory,且DefaultListableBeanFactory继承AbstractAutowireCapableBeanFactory,因此我们此处分析AbstractAutowireCapableBeanFactory即可。
- AbstractAutowireCapableBeanFactory的方法populateBean是主要实现,用于给bean实例填充数据
Spring创建Bean的流程
首先需要了解是Spring它创建Bean的流程,我把它的大致调用栈绘图如下:
对Bean的创建最为核心三个方法解释如下:
createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象
populateBean:填充属性,这一步主要是对bean的依赖属性进行注入(@Autowired)
initializeBean:回到一些形如initMethod、InitializingBean等方法
一文告诉你Spring是如何利用三级缓存巧妙解决Bean的循环依赖问题
BeanFactory中bean的生命周期
当请求getBean时,即实例化bean对象。ApplicationContext是在refresh()方法里立即实例化了所有的bean。
主要分为三阶段
- 实例化,创建Bean的过程,InstantiationAwareBeanPostProcessor作用于此
- 填充数据
- 初始化,BeanPostProcessor作用于此
阶段一:实例化
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()
此方法为核心方法,用于创建bean实例,填充bean属性,并执行后置方法
/**
* 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实现生成代理对象,则直接返回,不会调下面的方法
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;
}
}
//创建bean实例,调用populateBean填充属性
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
resolveBeforeInstantiation 的功能为:
如果有InstantiationAwareBeanPostProcessor实现的postProcessBeforeInstantiation方法生成代理对象,则直接返回,不会调下面的方法
@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;
}
注意:实例化之前执行InstantiationAwareBeanPostProcessor. postProcessBeforeInstantiation方法,当经过前置处理之后,返回的结果若不为空,那么会直接略过后续的Bean的创建而直接返回结果
::原因:resolveBeforeInstantiation只是针对有自定义的targetsource,因为自定义的targetsource不是spring的bean那么肯定不需要进行后续的一系列的实例化初始化。所以可以在resolveBeforeInstantiation直接进行proxy::
Spring源码解析(十一)Spring扩展接口InstantiationAwareBeanPostProcessor解析
Spring之InstantiationAwareBeanPostProcessor接口介绍 - 云+社区 - 腾讯云
Spring Aop之Target Source详解Java爱宝贝丶的博客-CSDN博客
阶段二:填充实例-populateBean实现
位于:AbstractAutowireCapableBeanFactory#populateBean
主要功能:
- 把Autowired注解的属性注入到实例中
- 执行实现了InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法修改实例
执行流程。如下:
- 获取属性列表 pvs
- 在属性被填充到 bean 前,应用后置处理自定义属性填充
- 根据名称或类型解析相关依赖
- 再次应用后置处理,用于动态修改属性列表 pvs 的内容
- 将属性应用到 bean 对象中
注意第3步,也就是根据名称或类型解析相关依赖(autowire)。该逻辑只会解析依赖,并不会将解析出的依赖立即注入到 bean 对象中。所有的属性值是在 applyPropertyValues 方法中统一被注入到 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 状态的机会。关于这段后置引用,官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无
* 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现
* InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议
* 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器。
*/
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;
}
}
}
}
/*
* 如果上面设置 continueWithPropertyPopulation = false,表明用户可能已经自己填充了
* bean 的属性,不需要 Spring 帮忙填充了。此时直接返回即可
*/
if (!continueWithPropertyPopulation) {
return;
}
// 根据名称或类型注入依赖
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 对象前,对属性的值进行相应的处理,
* 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
* 而是经过后置处理器修改后的内容
*/
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);
}
}
// 应用属性值到 bean 对象中
applyPropertyValues(beanName, mbd, bw, pvs);
阶段三:初始化实例
初始化过程主要包含以下几个过程:
- 执行BeanNameAware, BeanClassLoaderAware, BeanFactoryAware 接口实现
- 执行BeanPostProcessor.postProcessAfterInitialization:
- 执行InitializingBean接口的中afterPropertiesSet()方法(如果该实例实现)
- 执行实例init method
- 执行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;
}