带有AOP拦截器的Spring 3 MVC @Controller?

pak*_*man 11 java spring controller spring-mvc spring-aop

任何人都知道为什么显然不可能将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";
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的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>
Run Code Online (Sandbox Code Playgroud)

一切都很好.

但是当我添加:

    <aop:config>
        <aop:pointcut expression="execution(* org.xxx.*(..))" id="pc1"/>
        <aop:advisor advice-ref="hibernateInterceptor"  pointcut-ref="pc1" order="2" />
    </aop:config>
Run Code Online (Sandbox Code Playgroud)

控制器停止作为控制器(没有错误,只是它停止绑定到指定的URL)!

Sea*_*oyd 18

来自Spring MVC参考:

注意
使用控制器接口时(例如,对于AOP代理),请确保始终将所有映射注释(例如 @RequestMapping@SessionAttributes - )放在控制器接口上而不是实现类上.

当然,这个说明很好隐藏:-)

  • @pakman通常**需要**来注释实现类,因为注释不是从接口继承的,但是控制器注释逻辑在运行时(可能是代理)的实际bean上工作,而不是静态bean类 (3认同)

doa*_*hai 16

我遇到了同样的问题并找到了解决方案.

实际上,您的控制器(由@Controller注释)和您的方面(由@Aspect注释)应该在相同的Spring上下文中.

通常人们在dispatch-servlet.xmlxxx-servlet.xml中定义他们的控制器,并在主applicationContext.xml中定义他们的服务bean(包括方面).不起作用.

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

以上的论述不依赖于此

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

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

  • 天才!你救了我很多工作.非常感谢你! (2认同)