如何将@EnableTransactionManagement与StaticMethodMatcherPointcutAdvisor结合使用

时间:2013-12-04 07:55:07

标签: java spring transactions aop

鉴于以下服务:

public interface MyService {
    void method();
}

它的实施:

@Service
public class MyServiceImpl implements MyService {

    @Transactional
    @CustomAnnotation
    @Override
    public void method() {
        ...
    }
}

我想以下列方式使用StaticMethodMatcherPointcutAdvisor

public class MyPointcutAdvisor extends StaticMethodMatcherPointcutAdvisor {
   ...

    @Override       
    public boolean matches(Method method, Class targetClass) {
       Method m = method;
       if(annotationPresent(method)) {
           return true;
       }
       Class<?> userClass = ClassUtils.getUserClass(targetClass);
       Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
       specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
       if(annotationPresent(specificMethod )) {
           return true;
       }
       return false;
    }
    ...
}

问题是Spring使用InfrastructureAdvisorAutoProxyCreator创建该类的代理,而DefaultAdvisorAutoProxyCreator将为MyPointcutAdvisor创建代理,但MyPointcutAdvisor是仅将代理作为targetClass参数。因此,PointcutAdvisor找不到注释,因此不匹配。

为了完成,这是我的配置类:

@Configuration
@EnableTransactionManagement
public class MyConfiguration {

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }

    @Bean
    public MyPointcutAdvisor myPointcutAdvisor() {
        return new MyPointcutAdvisor();
    } 
    ...
}

我的问题是:有没有办法将@EnableTransactionManagementStaticMethodMatcherPointcutAdvisor结合使用?

解决方法:

  • @CustomAnnotation放入服务界面:我希望拥有干净的界面。
  • @Role(BeanDefinition.ROLE_INFRASTRUCTURE)添加到MyPointCutAdvisor bean配置,因此InfrastructureAdvisorAutoProxyCreator将创建代理。这似乎是错误的方式,因为这个bean不是基础设施
  • ProxyTransactionManagementConfiguration复制bean,删除@EnableTransactionManagement并移除@Role(BeanDefinition.ROLE_INFRASTRUCTURE),因此DefaultAdvisorAutoProxyCreator将创建代理,这是我当前的解决方法并导致以下配置:

    @Configuration
    public class MyWorkaroundConfiguration {
        @Bean
        public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
            return new DefaultAdvisorAutoProxyCreator();
        }
    
        @Bean
        public MyPointcutAdvisor myPointcutAdvisor() {
            return new MyPointcutAdvisor();
        }
    
        @Bean
        public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();
        }
    
        @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
                TransactionInterceptor transactionInterceptor) {
            BeanFactoryTransactionAttributeSourceAdvisor advisor =
                new BeanFactoryTransactionAttributeSourceAdvisor();
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            advisor.setAdvice(transactionInterceptor);
            return advisor;
        }
    
        @Bean
        public TransactionInterceptor transactionInterceptor(
                PlatformTransactionManager transactionManager) {
            TransactionInterceptor interceptor = new TransactionInterceptor();
            interceptor.setTransactionAttributeSource(transactionAttributeSource());
            interceptor.setTransactionManager(transactionManager);
            return interceptor;
        } 
        ...
    }
    

1 个答案:

答案 0 :(得分:1)

使用@EnableAspectJAutoProxy而不是DefaultAutoProxyCreator适用于我。

@Configuration
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class MyConfiguration {

}

这也允许使用像@Deinum这样的@Aspect建议。