Spring 3 MVC @Controller 与 AOP 拦截器?
任何人都知道为什么显然不可能将 AOP 与带注释的 MVC 控制器一起使用? (请参阅帖子)。 我有一个 @Controller,一旦我向它添加切入点,它就会停止工作。 问题不在于拦截器没有被调用,而在于 @Controller 只是停止工作(在日志中您可以看到,您得到的不是“映射的 URL 路径 [/xx] 到处理程序'Yyy'”),而是“无 URL”确定的路径”)。
我知道有一种通过 handlerMapping 将拦截器添加到控制器的机制,但我的问题特定于 AOP 拦截器。带注释的控制器不就是 Spring 容器中的 pojo 吗?与任何其他 pojo 一样?有什么区别?为什么?
@Controller
@RequestMapping("/user")
public class RestTestImpl implements RestTest {
@RequestMapping(value="/", method={RequestMethod.GET})
public @ResponseBody String deleteUsers(String arg) {
return "Xxxxx";
}
}
在我的 servlet-Context 中,我有:
<context:component-scan base-package="org.xxx.yyy"></context:component-scan>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
. . .
</bean>
一切都很好。
但是当我添加:
<aop:config>
<aop:pointcut expression="execution(* org.xxx.*(..))" id="pc1"/>
<aop:advisor advice-ref="hibernateInterceptor" pointcut-ref="pc1" order="2" />
</aop:config>
控制器不再是控制器(没有错误,只是停止绑定到指定的 URL)!
Anyone knows why apparently it is not possible to use AOP with annotated MVC Controllers? (see Post).
I have a @Controller that stops working as soon as I add a pointcut to it.
The problem is not that the interceptor is not being called, but rather the @Controller simply stops working (in the log you can see that instead of "Mapped URL path [/xx] onto handler 'Yyy'" you get a "no URL paths identified").
I know there is a mechanism for adding interceptors to controllers via the handlerMapping but my question is specific to AOP interceptors. Aren't annotated controllers just pojos in the Spring container as any other pojo? What is the difference? Why?
@Controller
@RequestMapping("/user")
public class RestTestImpl implements RestTest {
@RequestMapping(value="/", method={RequestMethod.GET})
public @ResponseBody String deleteUsers(String arg) {
return "Xxxxx";
}
}
In my servlet-Context I have:
<context:component-scan base-package="org.xxx.yyy"></context:component-scan>
<mvc:annotation-driven />
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
. . .
</bean>
And everything works just great.
But when I add:
<aop:config>
<aop:pointcut expression="execution(* org.xxx.*(..))" id="pc1"/>
<aop:advisor advice-ref="hibernateInterceptor" pointcut-ref="pc1" order="2" />
</aop:config>
The controller stops being a controller (no errors, simply it stops binding to the specified URL)!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自 Spring MVC 参考:
当然,这个注释被隐藏得很好:-)
From the Spring MVC Reference:
Granted, this note is well hidden :-)
我遇到了同样的问题并找到了解决方案。
实际上,您的控制器(由@Controller注释)和方面(由@Aspect注释)应该位于相同的Spring上下文中。
通常人们在 dispatch-servlet.xml 或 xxx-servlet.xml 中定义他们的控制器,并在主 applicationContext.xml 中定义他们的服务 bean(包括方面) 。这是行不通的。
当 Spring 初始化 MVC 上下文时,它将为您的控制器创建一个代理,但如果您的方面不在同一上下文中,Spring 将不会为它们创建拦截器。
上述 ssertion 不依赖
我已经测试了所有组合,只要满足以下条件,它们都可以工作控制器和各个方面都在相同的Spring 上下文中
I ran into the same issue and found out the solution.
Indeed your controller (annotated by @Controller) and your aspects (annotated by @Aspect) should be in the same Spring context.
Usually people define their controllers in the dispatch-servlet.xml or xxx-servlet.xml and their service beans (including the aspects) in the main applicationContext.xml. It will not work.
When Spring initializes the MVC context, it will create a proxy for your controller but if your aspects are not in the same context, Spring will not create interceptors for them.
The above ssertion does not depend
I've tested all the combinations and they all work as long as the controller & aspects are in the same Spring context
在不进行认真挖掘的情况下,我最好的猜测是因为您使用的 Spring 的 AOP 机制将目标类包装在代理类中,最终会丢失它们的注释,或者原始注释在编织后被删除。
我确信有一个更好的答案,并且当我想到更好更清晰的方式来呈现它时,我将扩展我的答案。
My best guess without doing some serious digging is because Spring's AOP mechanism that you are using is wrapping the target classes in proxy classes which end up loosing their annotation or the original annotation gets dropped after weaving.
I am sure there is a better answer and I'll expand on mine as I think of a better more clear way to present it.