带有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.xmlxxx-servlet.xml中定义他们的控制器,并在主applicationContext.xml中定义他们的服务bean(包括方面)。 不起作用。

当Spring初始化MVC上下文时,它将为您的控制器创建一个代理,但如果您的方面不在同一个上下文中,Spring将不会为它们创建拦截器。

以上的论述不依赖于此

  • 在您声明控制器/方面的方式上(通过手动XML声明或注释样式)
  • 您选择的代理样式(JDK代理或CGLIB)

我已经测试了所有组合,只要控制器和方面在相同的Spring上下文中它们都可以工作

我最好的猜测是没有进行一些严肃的挖掘,因为Spring正在使用的AOP机制是将目标类包装在代理类中,最终会丢失它们的注释,或者在编织后丢弃原始注释。

我相信有一个更好的答案,我会扩展我的,因为我想到一个更明确的方式来呈现它。