使用@Transactional导致问题的Spring DefaultAdvisorAutoProxyCreator

时间:2012-08-10 12:05:44

标签: spring aop shiro

我正在开发一个Spring MVC项目并尝试集成Apache Shiro以提高安全性。一切都只是游泳,直到我意识到Hibernate在单个查询后过早关闭会话/连接并导致lazyinit异常。毫不奇怪,我在做什么应该在一个交易中完成,所以会话没有关闭。

困境...

  1. 我尝试将@Transactional放在我的控制器方法上,但我得到了404。查看我的日志,我可以看到,当Spring引导时,如果@Transactional注释在控制器中的任何方法上,它将忽略我的HomeController中的任何映射。

  2. 没有@Transactional它加载就好了,我可以看到RequestMappingHandlerMapping bean看到我控制器中的所有@RequestMapping注释。

  3. 使用@Transactional但不使用DefaultAdvisorAutoProxyCreator,除了Shiro注释外,它可以正常工作。

  4. tldr: Shiro需要DefaultAdvisorAutoProxyCreator,但是如果我创建了那个bean,那么在使用@Transactional注释时Spring会爆炸。

    我正在寻求帮助,因为我完全不知道如何继续这一点。

1 个答案:

答案 0 :(得分:3)

这通常是因为当你在方法上放置@Transactional时,Spring会为该bean创建一个动态代理 - 如果bean实现了一个接口,那么就会根据该接口创建动态代理,否则CGLIB将用于创建代理。

在您的情况下,我猜测的问题是因为您可能已将控制器基于某个接口,或者您正在基于基类扩展它。这最终会创建一个基于该接口的代理,因此,当需要为您的请求创建映射时,Spring MVC可能无法从您的bean中找到您的映射。

修复可能有几个:

一个。您可以尝试强制代理基于CGLIB进行交易:

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

湾您可以使用纯Aspectj,加载时间编织或编译时间编织

℃。您可以将@Transactional移动到服务(具有接口)并将调用从控制器委派给服务,这样可以避免控制器上的@Transaction