0

Spring Web 在以下情况下会导致循环引用

  1. 启用 AspectJ 自动代理和事务管理
  2. 创建一个简单的bean,B1预计首先被加载
  3. 创建一个依赖于B1的ProxyFactoryBean,B2

下面是我的分析。

  1. Spring 尝试创建 Bean B1。此时,AnnotationAwareAspectJAutoProxyCreator BPP 启动。
  2. AutoProxyCreator 打算创建 TransactionAdvicer 并尝试查找 TransactionManagementConfigurer 类型的所有 bean
  3. B2 是一个工厂 bean(检查工厂 bean 类型的快捷方式也失败了),spring 需要创建完整的 bean B2 来比较类型。由于 B2 依赖于 B1,因此会产生循环引用。

一种解决方法是确保 Spring 首先加载一个虚拟 bean,比如 B0,没有 bean 会依赖它。

Java配置:

@Configuration
@DependsOn("testBean2")
@EnableTransactionManagement
public class TestConfig
{
   @Bean
   public PlatformTransactionManager transactionManager()
   {
      DriverManagerDataSource dataSource = new DriverManagerDataSource();
      // MySQL database we are using
      dataSource.setDriverClassName("com.mysql.jdbc.Driver");
      dataSource.setUrl("jdbc:mysql://localhost:3306/db");// change url
      dataSource.setUsername("username");// change userid
      dataSource.setPassword("password");// change pwd

      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>
4

1 回答 1

0

将您的@Bean声明移至一个@Configuration类。

它将防止一个bean方法被调用两次

于 2018-05-26T17:21:01.630 回答