带有AOP拦截器的Spring 3 MVC @Controller?
任何人都知道为什么显然不可能将AOP与带注释的MVC控制器一起使用? (见邮政 )。 我有一个@Controller,一旦我添加切入点就会停止工作。 问题不在于拦截器没有被调用,而是@Controller只是停止工作(在日志中你可以看到,而不是“映射的URL路径[/ xx]到处理器’Yyy’”你得到一个“没有URL”确定的路径“)。
我知道有一种通过handlerMapping向控制器添加拦截器的机制,但我的问题是特定于AOP拦截器。 注释控制器只是在Spring容器中像任何其他pojo一样pojos吗? 有什么不同? 为什么?
@Controller @RequestMapping("/user") public class RestTestImpl implements RestTest { @RequestMapping(value="/", method={RequestMethod.GET}) public @ResponseBody String deleteUsers(String arg) { return "Xxxxx"; } }
在我的servlet-Context中我有:
. . .
一切都很好。
但是当我添加:
控制器停止作为控制器(没有错误,只是它停止绑定到指定的URL)!
来自Spring MVC参考 :
注意
使用控制器接口(例如,用于AOP代理)时,请确保始终将所有映射注释 (例如@RequestMapping
和@SessionAttributes
) 放在控制器接口而不是实现类上。
当然,这个说明很好隐藏:-)
我遇到了同样的问题并找到了解决方案。
实际上,您的控制器(由@Controller注释)和您的方面(由@Aspect注释)应该在相同的Spring上下文中 。
通常人们在dispatch-servlet.xml或xxx-servlet.xml中定义他们的控制器,并在主applicationContext.xml中定义他们的服务bean(包括方面)。 不起作用。
当Spring初始化MVC上下文时,它将为您的控制器创建一个代理,但如果您的方面不在同一个上下文中,Spring将不会为它们创建拦截器。
以上的论述不依赖于此
- 在您声明控制器/方面的方式上(通过手动XML声明或注释样式)
- 您选择的代理样式(JDK代理或CGLIB)
我已经测试了所有组合,只要控制器和方面在相同的Spring上下文中它们都可以工作
我最好的猜测是没有进行一些严肃的挖掘,因为Spring正在使用的AOP机制是将目标类包装在代理类中,最终会丢失它们的注释,或者在编织后丢弃原始注释。
我相信有一个更好的答案,我会扩展我的,因为我想到一个更明确的方式来呈现它。