java 带有 AOP 拦截器的 Spring 3 MVC @Controller?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5862991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring 3 MVC @Controller with AOP interceptors?
提问by pakman
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").
任何人都知道为什么显然不可能将 AOP 与带注释的 MVC 控制器一起使用?(见帖子)。我有一个@Controller,一旦我向它添加切入点,它就会停止工作。问题不在于没有调用拦截器,而是 @Controller 只是停止工作(在日志中,您可以看到“映射 URL 路径 [/xx] 到处理程序 'Yyy'”,而是“无 URL”确定的路径”)。
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?
我知道有一种机制可以通过 handlerMapping 向控制器添加拦截器,但我的问题是特定于 AOP 拦截器的。与任何其他 pojo 一样,带注释的控制器不只是 Spring 容器中的 pojos 吗?有什么区别?为什么?
@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:
在我的 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>
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)!
控制器不再是控制器(没有错误,只是停止绑定到指定的 URL)!
回答by Sean Patrick Floyd
From the Spring MVC Reference:
Note
When using controller interfaces (e.g. for AOP proxying), make sure to consistently put all your mapping annotations- such as@RequestMapping
and@SessionAttributes
- on the controller interfacerather than on the implementation class.
注意
当使用控制器接口(例如用于 AOP 代理)时,请确保始终将所有映射注释- 例如@RequestMapping
和@SessionAttributes
-放在控制器接口上,而不是放在实现类上。
Granted, this note is well hidden :-)
当然,这个笔记隐藏得很好:-)
回答by doanduyhai
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.
实际上,您的控制器(由@Controller 注释)和方面(由@Aspect 注释)应该在同一个Spring 上下文中。
Usually people define their controllers in the dispatch-servlet.xmlor xxx-servlet.xmland their service beans (including the aspects) in the main applicationContext.xml. It will not work.
通常人们在dispatch-servlet.xml或xxx-servlet.xml 中定义他们的控制器,在主applicationContext.xml 中定义他们的服务 bean(包括方面)。不起作用。
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.
当 Spring 初始化 MVC 上下文时,它将为您的控制器创建一个代理,但如果您的方面不在同一上下文中,Spring 将不会为它们创建拦截器。
The above ssertion does not depend
上面的断言不依赖
- on the way your declare your controllers/aspects (by manual XML declaration or annotation style)
- on the proxying style you choose (JDK proxy or CGLIB)
- 在声明控制器/方面的方式(通过手动 XML 声明或注释样式)
- 在您选择的代理风格上(JDK 代理或 CGLIB)
I've tested all the combinations and they all work as long as the controller & aspects are in the same Spring context
我已经测试了所有组合,只要控制器和方面在同一个Spring 上下文中,它们都可以工作
回答by Andrew White
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.
我最好的猜测是因为您正在使用的 Spring 的 AOP 机制将目标类包装在代理类中,这些代理类最终会丢失它们的注释,或者原始注释在编织后被丢弃。
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.
我相信有一个更好的答案,我会在我想到更好更清晰的呈现方式时扩展我的答案。