简体   繁体   English

Spring Web-关于启用AspectJ和事务管理的通函

[英]Spring Web - Circular Reference on enabling AspectJ & Transaction Management

Spring Web results in circular reference under the following condition 在以下条件下,Spring Web产生循环引用

  1. Enable AspectJ AutoProxy & Transaction Management 启用AspectJ自动代理和事务管理
  2. Create a simple bean, B1 expected to be loaded first 创建一个简单的bean,预期将首先加载B1
  3. Create a ProxyFactoryBean, B2 that depends on B1 创建一个依赖于B1的ProxyFactoryBean,B2

Below is my analysis. 以下是我的分析。

  1. Spring tries to create Bean B1. Spring尝试创建Bean B1。 At this point, AnnotationAwareAspectJAutoProxyCreator BPP kicks in. 此时,AnnotationAwareAspectJAutoProxyCreator BPP开始运行。
  2. The AutoProxyCreator intends to create TransactionAdvicer & tries to find all beans of TransactionManagementConfigurer type AutoProxyCreator打算创建TransactionAdvicer并尝试查找TransactionManagementConfigurer类型的所有bean。
  3. B2 being a Factory bean (The shortcut to check factory bean type failed as well), spring needs to create complete bean B2 to compare the type. B2是工厂bean(检查工厂bean类型的快捷方式也失败了),spring需要创建完整的bean B2来比较类型。 As B2 is dependent on B1, it results in a circular reference. 由于B2依赖于B1,因此会产生循环参考。

One workaround was to ensure that Spring first loads a dummy bean say B0, that no bean will depend on. 一种解决方法是确保Spring首先加载一个虚假的bean,即B0,没有bean依赖。

Java Configuration: 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 Configuration: 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>

Move your @Bean declaration to a @Configuration class. 将您的@Bean声明移到@Configuration类。

It will prevent one bean method called twice 它将防止一个调用两次的bean方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM