自动装配的Spring Bean不是代理对象。

9

我正在开发一个连接到MySQL数据库的非常小的应用程序。

我试图创建表记录,但是出现了“没有事务在进行中”的错误。

我已经做好了所有需要的步骤:

  • 一个服务接口MyService和它的实现类MyServiceImpl
  • 我已经使用@Service对服务实现进行了注释
  • 在控制器中,我使用了接口名称作为@ Autowired MyService字段
  • 我有正确的事务配置,因为它最初是由Roo生成的
  • MyService.create(...)是一个公共方法,MyServiceImpl实现了该方法

但是,

当我远程调试并检查控制器的myService字段时,我看到的是类似于com.some.package.services.MyService @ 12345(而不是类似于$ Proxy73)的东西,这对我来说不正确,因为应该自动装配代理而不是目标bean(我认为这就是这个问题)。如果我正确的话,那么当在代理上调用带有@Transactional注释的公共方法时才会触发注释。

请告诉我为什么Spring在这种设置中注入目标bean。

谢谢


MyServiceImpl 是否已经使用 @Transactional 进行注解?你的 XML 文件中是否有 <tx:annotation-driven/> - Tomasz Nurkiewicz
1
谢谢回复,是的,我有 <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>。 - jakstack
2个回答

8
如果您启用了AspectJ事务管理(<tx:annotation-driven mode="aspectj" .../>),则事务应用程序会在同一类中进行就地处理,无论是在构建期间(编译时织入)还是在启动时(加载时织入)。不会创建新的类(例如使用时)也不会创建代理(例如使用Spring中的普通基于接口的AOP)。相反,MyServiceImpl的字节码被直接修改,而您甚至没有注意到。不幸的是,查看AOP的唯一方法是反编译您的类。如果您使用javap -c MyServiceImpl,您将找到大量对Spring事务层的引用。

1
谢谢Tomasz,你说的很有道理,感谢你。我反编译了这个类,这是你所说的吗:AnnotationTransactionAspect.aspectOf().ajc$before$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(this, ajc$tjp_0); localJobSpec1 = (JobSpec)super.create(jobSpec); } catch (Throwable localThrowable) { AnnotationTransactionAspect.aspectOf().ajc$afterThrowing$org_springframework_transaction_aspectj_AbstractTransactionAspect$2$2a73e96c(this, localThrowable); throw localThrowable; } AnnotationTransactionAspect.aspectOf().ajc$after等等。 - jakstack

-4
如果您正在使用Spring MVC,请确保在servlet上下文文件中仅扫描特定的控制器类。否则,它将扫描2次,并且应用程序上下文中不可用事务。

2
请停止在各处发布相同的复制/粘贴答案。请确保它与当前问题确实相关。 - ForceMagic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接