问题:
在 Spring 框架中,循环依赖指多个 Bean 之间形成依赖闭环的现象,主要分为三种类型:
- 自身依赖于自身、
- 互相循环依赖、
- 多组循环依赖。
按照现在的程序,一旦出现循环依赖,就会进入递归循环创建对象的无底洞,从而爆栈。
解决思路:
Spring通过三级缓存机制解决此问题,该机制允许多阶段管理Bean实例,支持早期暴露半成品对象以打破循环,同时兼容AOP代理等扩展功能。
Spring使用三级缓存管理Bean的不同创建阶段:
- 一级缓存(singletonObjects):存储完全初始化的Bean实例(属性填充和初始化方法执行完毕)。
- 二级缓存(earlySingletonObjects):存储早期暴露的半成品Bean实例(实例化但属性未填充)。
- 三级缓存(singletonFactories):存储ObjectFactory,用于创建早期Bean引用,支持AOP代理生成。
目前实际只完成了一级缓存。
而二级缓存可以简单解决循环依赖问题,但是二级缓存无法解决 AOP 场景中代理对象与原始对象引用不一致的问题,因此需要三级缓存。
三级缓存的优势:
- 支持AOP:三级缓存允许在早期暴露时生成代理对象,而非直接存储实例。
- 分离成品和半成品对象,避免污染一级缓存。
解决循环依赖的机制
核心类:
- DefaultSingletonBeanRegistry:管理三级缓存,提供getSingleton、addSingletonFactory等方法。
- AbstractAutowireCapableBeanFactory:处理Bean创建,包括早期暴露和属性填充。
解决步骤:
- 实例化Bean:创建Bean实例后,如果是单例且允许循环依赖,添加ObjectFactory到三级缓存(addSingletonFactory),用于生成早期引用。
- 获取依赖:在属性填充时,通过getSingleton方法按序查询:
- 先查一级缓存。
- 若无,查二级缓存。
- 若无,查三级缓存:执行ObjectFactory.getObject()生成早期实例(若需AOP,则生成代理),移入二级缓存。
- 处理循环:如果存在循环,依赖方可从二级或三级缓存获取早期实例,打破递归。
- 完成初始化:属性填充和初始化方法执行后,将实例移入一级缓存(addSingleton),移除二级和三级缓存条目。
对于AOP:getEarlyBeanReference方法在三级缓存中处理代理创建,确保代理对象在循环中被一致引用。
举例说明,引出问题:
背景: A,B循环依赖,且A被代理。
开始get A:A在实例化后,紧接着就提前暴露三级缓存(仅单例),这里只是保存该bean的创建方法,还没有执行。然后进入注入,创建B, B在属性注入式就拿到了A的第三级缓存,并执行A工厂的getObject拿到了A(的代理对象),存入第二级缓存(见getSingleton方法),走完B的创建过程,回到了A的属性注入过程,走完B的创建过程。
此处就有几个问题\值得关注的点:⭐⭐⭐⭐⭐(原教材没讲或者直接忽略了)
- “B在属性注入式就拿到了A的第三级缓存,并执行A工厂的getObject拿到了A(的代理对象),存入第二级缓存” 在这一步得到了A的代理对象,但是这个代理对象的属性还没有填充。
- 属性未填充并不影响 AOP 增强?。
- AOP 增强是基于方法拦截实现的,与目标对象的属性状态无关
- B的流程结束后执行的是原始A的逻辑(包括属性填充),但最后管理、返回的应该是A的代理对象:
- 代理对象始终持有目标对象的引用:所以原始对象填充属性了也会反映到代理对象
- 在
initializeBean
的最后阶段,Spring 会用二级缓存中的A的代理对象 P 替换原始对象 A。(同时也避免了二次代理)
- 就像上面说的,原始对象A在注入B时就产生了代理,后面不会再次代理,是有两个机制共同保证的:
- 1.上文中的“
initializeBean
的最后阶段会用二级缓存中的A的代理对象 P 替换原始对象 A” - 2.自动代理创建器(
DefaultAdvisorAutoProxyCreator
)的earlyProxyReferences记录了哪些 Bean 已经被生成过代理,避免二次代理。
- 1.上文中的“
以上问题的代码实现见下。我会在注释里再次讨论。
具体实现:
0.工程结构:
small-spring-step-16
└── src
├── main
│ └── java
│ └── cn.bugstack.springframework
│ ├── aop
│ │ ├── aspectj
│ │ │ └── AspectJExpressionPointcut.java
│ │ │ └── AspectJExpressionPointcutAdvisor.java
│ │ ├── framework
│ │ │ ├── adapter
│ │ │ │ └── MethodBeforeAdviceInterceptor.java
│ │ │ ├── autoproxy
│ │ │ │ └── MethodBeforeAdviceInterceptor.java
│ │ │ ├── AopProxy.java
│ │ │ ├── Cglib2AopProxy.java
│ │ │ ├── JdkDynamicAopProxy.java
│ │ │ ├── ProxyFactory.java
│ │ │ └── ReflectiveMethodInvocation.java
│ │ ├── AdvisedSupport.java
│ │ ├── Advisor.java
│ │ ├── BeforeAdvice.java
│ │ ├── ClassFilter.java
│ │ ├── MethodBeforeAdvice.java
│ │ ├── MethodMatcher.java
│ │ ├── Pointcut.java
│ │ ├── PointcutAdvisor.java
│ │ └── TargetSource.java
│ ├── beans
│ │ ├── factory
│ │ │ ├── annotation
│ │ │ │ ├── Autowired.java
│ │ │ │ ├── AutowiredAnnotationBeanPostProcessor.java
│ │ │ │ ├── Qualifier.java
│ │ │ │ └── Value.java
│ │ │ ├── config
│ │ │ │ ├── AutowireCapableBeanFactory.java
│ │ │ │ ├── BeanDefinition.java
│ │ │ │ ├── BeanFactoryPostProcessor.java
│ │ │ │ ├── BeanPostProcessor.java
│ │ │ │ ├── BeanReference.java
│ │ │ │ ├── ConfigurableBeanFactory.java
│ │ │ │ ├── InstantiationAwareBeanPostProcessor.java
│ │ │ │ └── SingletonBeanRegistry.java
│ │ │ ├── support
│ │ │ │ ├── AbstractAutowireCapableBeanFactory.java
│ │ │ │ ├── AbstractBeanDefinitionReader.java
│ │ │ │ ├── AbstractBeanFactory.java
│ │ │ │ ├── BeanDefinitionReader.java
│ │ │ │ ├── BeanDefinitionRegistry.java
│ │ │ │ ├── CglibSubclassingInstantiationStrategy.java
│ │ │ │ ├── DefaultListableBeanFactory.java
│ │ │ │ ├── DefaultSingletonBeanRegistry.java
│ │ │ │ ├── DisposableBeanAdapter.java
│ │ │ │ ├── FactoryBeanRegistrySupport.java
│ │ │ │ ├── InstantiationStrategy.java
│ │ │ │ └── SimpleInstantiationStrategy.java
│ │ │ ├── support
│ │ │ │ └── XmlBeanDefinitionReader.java
│ │ │ ├── Aware.java
│ │ │ ├── BeanClassLoaderAware.java
│ │ │ ├── BeanFactory.java
│ │ │ ├── BeanFactoryAware.java
│ │ │ ├── BeanNameAware.java
│ │ │ ├── ConfigurableListableBeanFactory.java
│ │ │ ├── DisposableBean.java
│ │ │ ├── FactoryBean.java
│ │ │ ├── HierarchicalBeanFactory.java
│ │ │ ├── InitializingBean.java
│ │ │ ├── ListableBeanFactory.java
│ │ │ ├── ObjectFactory.java
│ │ │ └── PropertyPlaceholderConfigurer.java
│ │ ├── BeansException.java
│ │ ├── PropertyValue.java
│ │ └── PropertyValues.java
│ ├── context
│ │ ├── annotation
│ │ │ ├── ClassPathBeanDefinitionScanner.java
│ │ │ ├── ClassPathScanningCandidateComponentProvider.java
│ │ │ └── Scope.java
│ │ ├── event
│ │ │ ├── AbstractApplicationEventMulticaster.java
│ │ │ ├── ApplicationContextEvent.java
│ │ │ ├── ApplicationEventMulticaster.java
│ │ │ ├── ContextClosedEvent.java
│ │ │ ├── ContextRefreshedEvent.java
│ │ │ └── SimpleApplicationEventMulticaster.java
│ │ ├── support
│ │ │ ├── AbstractApplicationContext.java
│ │ │ ├── AbstractRefreshableApplicationContext.java
│ │ │ ├── AbstractXmlApplicationContext.java
│ │ │ ├── ApplicationContextAwareProcessor.java
│ │ │ └── ClassPathXmlApplicationContext.java
│ │ ├── ApplicationContext.java
│ │ ├── ApplicationContextAware.java
│ │ ├── ApplicationEvent.java
│ │ ├── ApplicationEventPublisher.java
│ │ ├── ApplicationListener.java
│ │ └── ConfigurableApplicationContext.java
│ ├── core.io
│ │ ├── ClassPathResource.java
│ │ ├── DefaultResourceLoader.java
│ │ ├── FileSystemResource.java
│ │ ├── Resource.java
│ │ ├── ResourceLoader.java
│ │ └── UrlResource.java
│ ├── stereotype
│ │ └── Component.java
│ └── utils
│ ├── ClassUtils.java
│ └── StringValueResolver.java
└── test
└── java
└── cn.bugstack.springframework.test
├── bean
│ ├── Husband.java
│ ├── HusbandMother.java
│ ├── IMother.java
│ ├── SpouseAdvice.java
│ └── Wife.java
├── ApiTest.java
└── CircleTest.java
1.定义ObjectFactory接口:
/**
* 对象工厂接口,用于返回指定类型的对象实例。
* - 可能返回共享的单例对象,也可能返回新的独立对象,取决于具体实现。
* - 在 Spring 三级缓存中,常用于提前暴露 Bean 的引用,以解决循环依赖问题。
*/
public interface ObjectFactory<T> {
/**
* 获取对象实例
*
* @return 返回指定类型的对象
* @throws BeansException 获取过程中可能抛出的异常
*/
T getObject() throws BeansException;
}
2. 设置三级缓存
DefaultSingletonBeanRegistry:
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
// 一级缓存,普通对象
private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
// 二级缓存,提前暴漏对象,没有完全实例化的对象
protected final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>();
// 三级缓存,存放代理对象
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>();
//注册了销毁回调的 Bean 对象的容器
private final Map<String, DisposableBean> disposableBeans = new LinkedHashMap<>();
/** 缓存中用于表示 null 值的特殊标记对象,避免存储 null 导致异常 */
protected static final Object NULL_OBJECT = new Object();
/**
* 销毁所有单例 Bean 对象。
*
* 该方法会遍历容器中所有已注册的实现了 DisposableBean 接口的 Bean(存储在 disposableBeans 中),
* 并按注册顺序的逆序依次调用它们的 destroy() 方法完成销毁。
*
* 逆序销毁是为了保证依赖关系正确释放(先销毁依赖者,再销毁被依赖者)。
*
* 销毁过程中如果发生异常,会包装成 BeansException 并抛出,确保调用者能感知销毁失败。
*/
public void destroySingletons() {
Set<String> keySet = this.disposableBeans.keySet();
Object[] disposableBeanNames = keySet.toArray();
//i倒序遍历:逆序销毁时因为被加入容器的顺序就暗含了依赖顺序
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
Object beanName = disposableBeanNames[i];
DisposableBean disposableBean = disposableBeans.remove(beanName);
try {
disposableBean.destroy();
} catch (Exception e) {
throw new BeansException("Destroy method on bean with name '" + beanName + "' threw an exception", e);
}
}
}
@Override
public Object getSingleton(String beanName) {
// 1. 优先从一级缓存获取(完全初始化的单例对象)
Object singletonObject = singletonObjects.get(beanName);
if (null == singletonObject) {
// 2. 一级缓存没有,则从二级缓存获取(半成品对象/代理对象)
singletonObject = earlySingletonObjects.get(beanName);
if (null == singletonObject) {
// 3. 二级缓存也没有,则从三级缓存获取(ObjectFactory 提前暴露的对象工厂)
ObjectFactory<?> singletonFactory = singletonFactories.get(beanName);
if (singletonFactory != null) {
// 通过工厂创建对象(可能是代理对象)
singletonObject = singletonFactory.getObject();
// 放入二级缓存,并移除三级缓存
earlySingletonObjects.put(beanName, singletonObject);
singletonFactories.remove(beanName);
}
}
}
return singletonObject;
}
/**
* 注册单例对象到一级缓存,同时清理二、三级缓存
*/
public void registerSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
earlySingletonObjects.remove(beanName);
singletonFactories.remove(beanName);
}
/**
* 向三级缓存添加对象工厂,用于提前暴露对象
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory){
if (!this.singletonObjects.containsKey(beanName)) {
// 如果一级缓存中没有成品对象
// 1. 将对象工厂放入三级缓存(用于生成代理或提前引用)
this.singletonFactories.put(beanName, singletonFactory);
// 2. 移除二级缓存中的半成品对象(优先保证代理对象生效)
this.earlySingletonObjects.remove(beanName);
}
}
/**
* 注册需要销毁的 Bean(容器关闭时调用 destroy)
*/
public void registerDisposableBean(String beanName, DisposableBean bean) {
disposableBeans.put(beanName, bean);
}
}
3.提前暴露对象:
核心原则:
- 在实例化 Bean 之后、属性注入前,把 Bean 放入三级缓存。
- 在注入属性时,如果发现依赖 Bean 正在创建,就先从二级或三级缓存拿,避免无限递归。
3.1首先扩展一下InstantiationAwareBeanPostProcessor:
添加:
/**
* 在 Bean 对象执行初始化方法之后,执行此方法
*
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
/**
* 用于提前斯暴露Bean的引用,解决循环依赖问题
* 属于InstantiationAwareBeanPostProcessor接口的默认方法
* @param bean 实例化后的Bean对象
* @param beanName Bean的名称
* @return 早期暴露的Bean引用(默认返回原始Bean)
*/
default Object getEarlyBeanReference(Object bean, String beanName) {
return bean;
}
3.2 DefaultAdvisorAutoProxyCreator新增earlyProxyReferences及相关机制:
/**
* 自动代理创建器,自动扫描容器中所有的 AspectJExpressionPointcutAdvisor,
* 根据切点匹配结果对目标Bean生成代理。
*
* 实现了 InstantiationAwareBeanPostProcessor,可以在 Bean 实例化前替换成代理对象。
*/
public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
private DefaultListableBeanFactory beanFactory;
// 记录已经生成过早期代理对象的 Bean 名称
private final Set<Object> earlyProxyReferences =
Collections.synchronizedSet(new HashSet<>());
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
// 这里强转是为了方便后续调用 getBeansOfType 方法
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
}
/**
* 在 Bean 实例化之前尝试返回代理对象。
* @param beanClass 待创建Bean的类
* @param beanName Bean名称
* @return 如果匹配切面返回代理,否则返回 null 继续创建原Bean
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// 目前先直接返回null,后期处理循环依赖问题时才需要提前创建代理对象并暴露
return null;
}
/**
* 判断是否为Spring基础设施类,避免代理这些类。
*/
private boolean isInfrastructureClass(Class<?> beanClass) {
return Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 不做处理,直接返回原始bean
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (!earlyProxyReferences.contains(beanName)) {
return wrapIfNecessary(bean, beanName);
}
// 已经提前代理过,直接返回早期代理对象,避免二次代理
return bean;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return pvs;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
earlyProxyReferences.add(beanName);
return wrapIfNecessary(bean, beanName);
}
private Object wrapIfNecessary(Object bean, String beanName) {
// 排除Spring自身基础设施类,防止循环代理
if (isInfrastructureClass(bean.getClass())) {
return bean; // 不代理,直接返回原对象
}
// 获取所有切面通知组合对象
Collection<AspectJExpressionPointcutAdvisor> advisorCollection =
beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();
List<AspectJExpressionPointcutAdvisor> advisors = new ArrayList<>(advisorCollection);
// 准备代理相关配置
AdvisedSupport advisedSupport = new AdvisedSupport();
advisedSupport.setTargetSource(new TargetSource(bean));
advisedSupport.setProxyTargetClass(bean.getClass().getInterfaces().length == 0);
// 遍历所有的切面通知器(Advisor)
for (AspectJExpressionPointcutAdvisor advisor : advisors) {
// 检查当前通知器的切入点是否匹配目标Bean的类
// getClassFilter()获取类过滤器,matches()判断目标类是否符合切入点表达式
if (advisor.getPointcut().getClassFilter().matches(bean.getClass())) {
// 如果匹配,则将该通知器添加到通知支持类中
advisedSupport.addAdvisor(advisor); // 存储匹配的通知器
}
}
// 检查是否有匹配的通知器
if (!advisedSupport.getAdvisors().isEmpty()) {
// 如果有匹配的通知器,使用代理工厂创建代理对象并返回
return new ProxyFactory(advisedSupport).getProxy();
}
// 如果没有匹配的通知器,直接返回原始Bean对象
return bean;
}
}
3.3AbstractAutowireCapableBeanFactory:
注意提前暴露机制与initializeBean的改动。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
//定义了一个创建对象的实例化策略属性类 InstantiationStrategy instantiationStrategy,这里我们选择了 Cglib 的实现类
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
@Override
protected Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) throws BeansException {
Object bean = null;
try {
// 提前代理,提供一个机会来返回一个自定义的 bean 实例,从而跳过 Spring 默认的 bean 实例化、属性注入等流程。
bean = resolveBeforeInstantiation(beanName, beanDefinition);
if (null != bean) {
return bean;
}
} catch (Exception e) {
throw new BeansException("Failed during resolveBeforeInstantiation for bean: " + beanName, e);
}
try {
// 创建实例
bean = createBeanInstance(beanDefinition, beanName, args);
} catch (Exception e) {
throw new BeansException("Failed to create bean instance for: " + beanName, e);
}
// --- 提前暴露三级缓存(仅单例) ---
//这里只是保存该bean的创建方法,还没有执行
/**
* 执行时机:
* 假设这里A被代理,创建A,暴露了第三级缓存,进入属性注入,创建B,
* B在属性注入式就拿到了A的第三级缓存,并执行A工厂的getObject拿到了A(的代理对象),存入第二级缓存(见getSingleton方法),走完B的创建过程,
* 回到了A的属性注入过程,走完B的创建过程
*/
if (beanDefinition.isSingleton()) {
Object finalBean = bean;
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, beanDefinition, finalBean));
}
// -----------------------------
// postProcessAfterInstantiation,可能阻止属性注入
// -----------------------------
boolean continueWithPropertyPopulation = applyBeanPostProcessorsAfterInstantiation(beanName, bean);
if (!continueWithPropertyPopulation) {
return bean; // 不再进行属性填充
}
try {
// 在设置 Bean 属性之前,允许 AutowiredAnnotationBeanPostProcessor 修改属性值(@Autowired、@Value)
applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Failed to process @Autowired/@Value annotations for bean: " + beanName, e);
}
try {
// 注入属性
applyPropertyValues(bean, beanName, beanDefinition);
} catch (Exception e) {
throw new BeansException("Failed to apply property values for bean: " + beanName, e);
}
try {
// 执行 Bean 的初始化方法和 BeanPostProcessor 的前置和后置处理方法
bean = initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Failed to initialize bean: " + beanName, e);
}
//注册可销毁的 Bean
registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);
// 判断 SCOPE_SINGLETON、SCOPE_PROTOTYPE
Object exposedObject = bean;
if (beanDefinition.isSingleton()) {
// 获取代理对象
exposedObject = getSingleton(beanName);
registerSingleton(beanName, exposedObject);
}
return exposedObject;
}
/**
* 获取Bean的早期引用,用于处理循环依赖
* 会遍历所有BeanPostProcessor,执行其getEarlyBeanReference方法
* @param beanName Bean名称
* @param beanDefinition Bean的定义信息
* @param bean 原始Bean实例
* @return 经过处理后的早期暴露引用(可能被增强,如AOP代理)
*/
protected Object getEarlyBeanReference(String beanName, BeanDefinition beanDefinition, Object bean) {
Object exposedObject = bean;
// 遍历所有Bean后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 只处理InstantiationAwareBeanPostProcessor类型的处理器
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 调用处理器的早期引用方法进行处理
Object current = ((InstantiationAwareBeanPostProcessor) bp)
.getEarlyBeanReference(exposedObject, beanName);
// 如果处理器返回了新的引用,则更新暴露的引用
if (current != null) {
exposedObject = current;
}
}
}
// 返回最终处理后的早期引用
return exposedObject;
}
/**
* 初始化 Bean 的过程:
* 1. 调用实现了 Aware 接口的回调方法,注入相应的容器资源。
* 2. 执行所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法。
* 3. 调用 Bean 自定义的初始化方法(如 afterPropertiesSet 或配置的 init-method)。
* 4. 执行所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。
*/
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {
// 1. 处理Aware接口回调(注入容器核心资源)
// 让Bean能够感知到容器相关信息(如Bean名称、BeanFactory等)
if (bean instanceof Aware) {
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
}
// 2. 执行初始化前置处理器(BeanPostProcessor)
// 例如:@PostConstruct注解标注的方法会在此阶段执行
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 3. 执行Bean自身的初始化方法
try {
// 调用InitializingBean接口的afterPropertiesSet方法
// 或自定义的init-method初始化方法
// 此时Bean的属性已完成填充,可执行初始化逻辑
invokeInitMethods(beanName, wrappedBean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);
}
// 4. 执行初始化后置处理器
// 无循环依赖时:AOP代理在此阶段通过wrapIfNecessary创建
// 有循环依赖时:因advisedBeans缓存直接返回原始对象(早期代理已创建)
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
// 5. 循环依赖场景:复用早期代理对象(核心逻辑)
// 从二级缓存获取早期暴露的代理对象(若存在)
Object earlySingletonReference = getSingleton(beanName);
if (earlySingletonReference != null) {
// 若经过后置处理后仍是原始对象,说明需要替换为早期代理
// 保证最终返回的是代理对象,与循环依赖中已注入的对象一致
if (wrappedBean == bean) {
wrappedBean = earlySingletonReference;
}
}
// 最终返回的对象:
// - 无循环依赖:正常代理对象或原始对象
// - 有循环依赖:早期创建的代理对象(保证引用一致性)
return wrappedBean;
}
/**
* 调用 Bean 的初始化方法
*/
private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition) throws Exception {
// 1. 实现接口 InitializingBean
if (wrappedBean instanceof InitializingBean) {
((InitializingBean) wrappedBean).afterPropertiesSet();
}
// 2. 配置信息 init-method
String initMethodName = beanDefinition.getInitMethodName();
if (StrUtil.isNotEmpty(initMethodName)) {
Method initMethod = beanDefinition.getBeanClass().getMethod(initMethodName);
if (null == initMethod) {
throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'");
}
initMethod.invoke(wrappedBean);
}
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (null == current) return result;
result = current;
}
return result;
}
/**
* Bean 实例化后对于返回 false 的对象,不再执行后续属性填充操作
*
* @param beanName 当前 Bean 的名称
* @param bean 当前 Bean 实例
* @return 如果返回 true,则继续填充属性;返回 false,则跳过属性填充
*/
private boolean applyBeanPostProcessorsAfterInstantiation(String beanName, Object bean) {
// 默认继续执行属性填充
boolean continueWithPropertyPopulation = true;
// 遍历所有注册的 BeanPostProcessor
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
// 只处理实现了 InstantiationAwareBeanPostProcessor 的处理器
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor instantiationAwareBeanPostProcessor =
(InstantiationAwareBeanPostProcessor) beanPostProcessor;
// 调用 postProcessAfterInstantiation 方法,如果返回 false,就不填充属性
if (!instantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bean, beanName)) {
continueWithPropertyPopulation = false;
break; // 一旦有处理器返回 false,立即停止遍历
}
}
}
// 返回是否继续执行属性填充
return continueWithPropertyPopulation;
}
/*
* 执行所有注册的 BeanPostProcessor 的 postProcessBeforeInitialization 方法
* 用于在 Bean 初始化方法执行前,做一些预处理操作
*/
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (null == current) return result;
result = current;
}
return result;
}
/*
* 执行所有注册的 BeanPostProcessor 的 postProcessAfterInitialization 方法
* 用于在 Bean 初始化方法执行后,做一些扩展操作(比如 AOP 动态代理等)
*/
protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) {
Constructor constructorToUse = null;
Class beanClass = beanDefinition.getBeanClass();
//通过 beanClass.getDeclaredConstructors() 方式可以获取到你所有的构造函数,是一个集合
Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
//循环比对匹配构造函数与args,此处简化为数量对比,实际还需比对入参类型
for (Constructor ctor : declaredConstructors) {
if (null != args && ctor.getParameterTypes().length == args.length) {
constructorToUse = ctor;
break;
}
}
return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args);
}
private void applyPropertyValues(Object bean, String beanName, BeanDefinition beanDefinition) {
//从beanDefinition得到这个bean的propertyValues。依次注入。如果要注入的属性时另一个bean,就getBean(创建或获取)。
try {
PropertyValues propertyValues = beanDefinition.getPropertyValues();
for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
String name = propertyValue.getName();
Object value = propertyValue.getValue();
//instanceof:判断value这个对象是否为BeanReference的实例
if (value instanceof BeanReference) {
// A 依赖 B,获取 B 的实例化
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getBeanName());
}
// 属性填充(BeanUtil是hutool的)
BeanUtil.setFieldValue(bean, name, value);
}
} catch (Exception e) {
throw new BeansException("Error setting property values:" + beanName,e);
}
}
public InstantiationStrategy getInstantiationStrategy() {
return instantiationStrategy;
}
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
/**
* 若 Bean 实现了 DisposableBean 或配置了销毁方法,则注册其销毁适配器。
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, BeanDefinition beanDefinition) {
// 非 Singleton 类型的 Bean 不执行销毁方法
if (!beanDefinition.isSingleton()) return;
if (bean instanceof DisposableBean || StrUtil.isNotEmpty(beanDefinition.getDestroyMethodName())) {
// 使用 DisposableBeanAdapter 适配器包装 Bean
// 适配器实现了 DisposableBean 接口,
// 这样无论 Bean 是实现接口销毁,还是通过配置销毁方法,
// 都能统一以 DisposableBean 形式注册到容器,方便统一管理和调用销毁逻辑。
registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, beanDefinition));
}
}
/**
* 在 Bean 实例化前调用,尝试通过 InstantiationAwareBeanPostProcessor
* 返回代理对象,若有则跳过默认实例化。
* 返回非空对象时,还会执行后置初始化处理。
*/
protected Object resolveBeforeInstantiation(String beanName, BeanDefinition beanDefinition) {
// 调用所有 InstantiationAwareBeanPostProcessor,尝试返回代理或替代对象
Object bean = applyBeanPostProcessorBeforeInstantiation(beanDefinition.getBeanClass(), beanName);
if (bean != null) {
// 如果前置处理返回了代理对象,继续调用所有 BeanPostProcessor 的
// postProcessAfterInitialization,保证代理对象完成生命周期的后置处理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
// 返回代理对象(非空)或 null(继续默认实例化)
return bean;
}
/**
* 遍历所有 BeanPostProcessor,调用实现了 InstantiationAwareBeanPostProcessor
* 的 postProcessBeforeInstantiation,返回第一个非空结果。
*/
public Object applyBeanPostProcessorBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
// 遍历所有注册的 BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 过滤出实现了 InstantiationAwareBeanPostProcessor 的处理器
if (processor instanceof InstantiationAwareBeanPostProcessor) {
// 调用 postProcessBeforeInstantiation 方法尝试返回代理对象或替代 Bean
Object result = ((InstantiationAwareBeanPostProcessor) processor).postProcessBeforeInstantiation(beanClass, beanName);
// 如果返回非空对象,表示已创建代理或替代对象,直接返回,跳过默认实例化
if (result != null) return result;
}
}
// 如果所有处理器都未返回代理,返回 null,继续默认实例化流程
return null;
}
/**
* 在为 Bean 填充属性(依赖注入)之前,允许 BeanPostProcessor 对属性值进行修改。
*
* 这里主要是为了支持类似 @Autowired、@Value、@Resource 等注解驱动的依赖注入,
* 因为它们依赖于 InstantiationAwareBeanPostProcessor 在属性设置前进行解析与赋值。
*
* @param beanName 当前 Bean 的名称
* @param bean 已经实例化好的 Bean 对象(构造方法已调用,但属性还未注入)
* @param beanDefinition Bean 对应的定义信息(包含属性、构造参数等)
*/
protected void applyBeanPostProcessorsBeforeApplyingPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) {
// 遍历当前容器中注册的所有 BeanPostProcessor
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
// 只有 InstantiationAwareBeanPostProcessor 才能在属性设置前做处理
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
// 调用其 postProcessPropertyValues 方法,让它有机会修改 Bean 的属性值
// 例如 AutowiredAnnotationBeanPostProcessor 会在这里解析 @Autowired 并生成对应的依赖注入 PropertyValue
PropertyValues pvs = ((InstantiationAwareBeanPostProcessor) beanPostProcessor)
.postProcessPropertyValues(beanDefinition.getPropertyValues(), bean, beanName);
// 如果处理器返回了新的属性值集合,则合并到 BeanDefinition 的属性列表中
if (null != pvs) {
for (PropertyValue propertyValue : pvs.getPropertyValues()) {
beanDefinition.getPropertyValues().addPropertyValue(propertyValue);
}
}
}
}
}
}
3.4AutowiredAnnotationBeanPostProcessor补充实现:
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
测试:
准备:
新增一个用于循环依赖的类:
@Component
public class TempService {
@Autowired
private IUserService userService;
public void queryUserInfo() {
String result = userService.queryUserInfo();
System.out.println("TempService 调用了 userService.queryUserInfo():"+result);
}
public void talk() {
System.out.println("TempService:talk! ");
}
}
新增方法与属性。注意接口中也要定义方法。
@Component("userService")
public class UserService implements IUserService {
@Value("${token}")
private String token;
@Autowired
private UserDao userDao;
@Autowired
private TempService tempService;
public String queryUserInfo() {
try {
Thread.sleep(new Random(1).nextInt(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
return userDao.queryUserName("10001") + "," + token;
}
public void useTempService() {
tempService.talk();
}
@Override
public String toString() {
return "UserService#token = { " + token + " }";
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
xml配置:
与之前相比修改了aop介入点:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean class="com.miniSpring.beans.factory.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:token.properties"/>
</bean>
<!-- 自动代理创建器:-->
<bean class="com.miniSpring.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<!-- aop组合1-->
<bean id="beforeAdvice1" class="com.miniSpring.test.bean.LogBeforeAdvice"/>
<bean id="methodInterceptor1" class="com.miniSpring.aop.adapter.MethodBeforeAdviceInterceptor">
<property name="advice" ref="beforeAdvice1"/>
</bean>
<bean id="pointcutAdvisor1" class="com.miniSpring.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="expression" value="execution(* com.miniSpring.test.bean.IUserService.queryUserInfo(..))"/>
<property name="advice" ref="methodInterceptor1"/>
<property name="order" value="3"/>
</bean>
<!-- aop组合2-->
<bean id="afterAdvice2" class="com.miniSpring.test.bean.LogAfterAdvice"/>
<bean id="methodInterceptor2" class="com.miniSpring.aop.adapter.MethodAfterAdviceInterceptor">
<property name="advice" ref="afterAdvice2"/>
</bean>
<bean id="pointcutAdvisor2" class="com.miniSpring.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="expression" value="execution(* com.miniSpring.test.bean.IUserService.queryUserInfo(..))"/>
<property name="advice" ref="methodInterceptor2"/>
<property name="order" value="2"/>
</bean>
<!-- aop组合3-->
<bean id="aroundAdvice3" class="com.miniSpring.test.bean.LogAroundAdvice"/>
<bean id="methodInterceptor3" class="com.miniSpring.aop.adapter.MethodAroundAdviceInterceptor">
<property name="advice" ref="aroundAdvice3"/>
</bean>
<bean id="pointcutAdvisor3" class="com.miniSpring.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="expression" value="execution(* com.miniSpring.test.bean.IUserService.queryUserInfo(..))"/>
<property name="advice" ref="methodInterceptor3"/>
<property name="order" value="1"/>
</bean>
<component-scan base-package="com.miniSpring.test.bean"/>
<!-- <bean id="tempService" class="com.miniSpring.test.bean.TempService">-->
<!-- <property name="userService" ref="userService"></property>-->
<!-- </bean>-->
</beans>
单元测试:
@Test
public void test() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
IUserService userService = applicationContext.getBean("userService", IUserService.class);
TempService tempService = (TempService) applicationContext.getBean("tempService");
tempService.queryUserInfo();
userService.useTempService();
}
结果:
环绕通知: 方法 queryUserInfo 执行前
前置通知: 方法 queryUserInfo 即将执行
后置通知: 方法 queryUserInfo 执行完毕, 返回值: CMD137,北京,亦庄,123_TEST_TOKEN_321
环绕通知: 方法 queryUserInfo 执行后, 返回值: CMD137,北京,亦庄,123_TEST_TOKEN_321
TempService 调用了 userService.queryUserInfo():CMD137,北京,亦庄,123_TEST_TOKEN_321
TempService:talk!
Process finished with exit code 0
可以看到循环依赖问题解决了,aop增强也依然生效。