Spring中@Transactional无法用在接口的实现类

  • 2016-10-09
  • 0
  • 0

以Spring 3.x为例,代码如下:

  1.  // IProcessor.java
  2.  package example;
  3.  
  4.  public interface IProcessor {
  5.    void execute();
  6.  }
  7.  
  8.  // JavatangProcessor.java
  9.  package example.impl;
  10.  
  11.  import example.IProcessor;
  12.  
  13.  @Component
  14.  @Transactional
  15.  public class JavatangProcessor implements IProcessor {
  16.  
  17.    @Override
  18.    public void execute() {
  19.     
  20.    }
  21.  }

xml配置文件内容如下:

  1.  ...
  2.  <context:component-scan base-package="example" />
  3.  <tx:annotation-driven transaction-manager="transactionManager" />

如果在其他地方使用@Autowired注入JavatangProcessor的话,在启动工程的时候会出现类似下面的错误信息:

java.lang.IllegalArgumentException: Can not xxx.javatangProcessor field JavatangProcessor to $Proxy41
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:657)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)

这是因为tx:annotation-driven默认情况下Spring使用的是基于接口的代理模式,在这种情况下子类无法直接进行初始化并进行引用,解决方法是在tx:annotation-driven中将proxy-target-class属性设置为true,即创建子类来代理业务类,xml配置文件修改成:

  1.  <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

如果是Spring 2.x的话需要设置成:

  1.  <aop:aspectj-autoproxy/>

参考资料:
Spring3事务管理——使用@Transactional 注解
Spring @Transactional doesn't work with other annotations?

评论

还没有任何评论,你来说两句吧