You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

启用AspectJ与事务管理时Spring Web循环依赖问题分析与解决

Spring Web循环引用的触发场景、根源分析与解决方案

我之前在项目里碰到过一模一样的Spring循环引用问题,刚好对应你描述的场景,下面给你详细拆解:

触发循环引用的三个必要条件

  • 同时启用AspectJ AutoProxy和事务管理
  • 定义一个预期会被优先加载的简单Bean(比如示例中的B1)
  • 创建依赖上述简单Bean的ProxyFactoryBean类型Bean(比如示例中的B2)

问题的深层原因

Spring容器初始化时的执行链路导致了这个死循环:

  1. Spring开始实例化Bean B1,此时AnnotationAwareAspectJAutoProxyCreator后置处理器启动工作
  2. 这个AutoProxyCreator需要创建TransactionAdvicer,而创建它的过程中会去查找所有TransactionManagementConfigurer类型的Bean
  3. 由于B2是Factory Bean,而且Spring的Factory Bean快捷类型检查机制失效了,Spring必须完整实例化B2才能判断它的类型,但B2本身依赖B1,这就形成了B1→TransactionAdvicer→B2→B1的循环依赖链

快速解决办法

一个简单且有效的方案是:让Spring优先加载一个完全不依赖其他Bean的虚拟Bean(比如示例中的testBean2),通过调整初始化顺序来打破这个循环。

Java配置示例

@Configuration 
@DependsOn("testBean2") 
@EnableTransactionManagement 
public class TestConfig { 
    @Bean 
    public PlatformTransactionManager transactionManager() { 
        DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
        dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
        dataSource.setUrl("jdbc:mysql://localhost:3306/db");// 根据你的数据库环境修改
        dataSource.setUsername("username");// 替换为实际用户名
        dataSource.setPassword("password");// 替换为实际密码
        PlatformTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); 
        return transactionManager; 
    } 
}

XML配置示例

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="http://www.springframework.org/schema/context" 
       xmlns:aop="http://www.springframework.org/schema/aop" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> 
    <aop:aspectj-autoproxy /> 
    <context:component-scan base-package="test.config" /> 
    <bean id="testBean2" class="test.beans.TestBean2" /> 
    <bean id="testTransactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"> 
        <property name="transactionManager" ref="transactionManager" /> 
        <property name="transactionAttributes"> 
            <props> 
                <prop key="audit">PROPAGATION_REQUIRES_NEW</prop> 
            </props> 
        </property> 
    </bean> 
    <bean id="testBean1" class="org.springframework.aop.framework.ProxyFactoryBean" depends-on="testBean2"> 
        <property name="target"> 
            <bean class="test.beans.TestBean1" /> 
        </property> 
        <property name="interceptorNames"> 
            <list> 
                <value>testTransactionInterceptor</value> 
            </list> 
        </property> 
    </bean> 
</beans>

内容的提问来源于stack exchange,提问作者Prasanna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:03:56