SpringMVC关于AOP拦截controller的注意事项

 SpringMVC关于AOP拦截controller的注意事项


       在网上也找了不少资料,但是感觉网上都没说清楚,在这里我把自己亲自验证的结果和配置方法在这里详细的讲解:

       首先aop切面是可以拦截controller层的。这一点再次强调一下,只不过它是有条件的。(条件就是如下3点: 请仔细,耐心的读完下面3句英文
        Indeed your controller (annotated by @Controller) and your aspects (annotated by @Aspect) should be in the same Spring context. (我自己翻译的,英文不好请别吐槽大笑
    1.Controller层和你自己定义的切面,必须在相同的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. 
    2.通常大家会把 controllers 定义在dispatch-servlet.xml 或者 xxx-servlet.xml 这样的配置文件中,但是把自定义的切面放在spring的主配置文件 applicationContext.xml中。这样子导致controller和你的切面不在同一个context中,从而你的切面类逻辑不会拦截对应的controller.

    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. 
 
   
3.当spring初始化MVC的context的时候,它会同时为 controller 创建代理,但是如果自定义切面没有和mvc在同一个context中,那么你的切面是不会去拦截这些controller 的

综合上面的三点:具体到我们如何实践呢?
               先看如下配置文件,然后看下面的分析(这个xml 是图中的 applicationContext.xml 主配置文件)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:tx="http://www.springframework.org/schema/tx"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:mvc="http://www.springframework.org/schema/mvc"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
     http://www.springframework.org/schema/tx  
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
     http://www.springframework.org/schema/aop  
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
     http://www.springframework.org/schema/mvc
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
     http://www.springframework.org/schema/context  
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:component-scan base-package="com.yt.*" />
	 <!--拦截controller层的方法,需要配置注解扫描 切面类 -->
	 <context:component-scan base-package="com.memcached" />
	 <aop:aspectj-autoproxy proxy-target-class="true"/>
	 
	<!-- 那些类的哪些方法参与事务 -->
	<aop:config proxy-target-class="true">
		<aop:pointcut id="allServiceMethod"
			expression="execution(* com.yt.*.service.*.*(..))" />
		<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice" />
	</aop:config>
</beans>  

1.配置文件中需要把切面类和controller 放在同一个spring的xml配置文件中,如下两个配置证明了,上述英文说明的第一点
<!--这个扫描配置,com.yt下面所有的包都扫描,但是没有扫描com.memcached这个包下的切面类-->         
<context:component-scan base-package="com.yt.*" />
<!--拦截controller层的方法,需要配置注解扫描 切面类(其实切面类就是anotationAspect.java),这里必选配置启动扫描 --> 
<context:component-scan base-package="com.memcached" />
<!--注意不要忘记,使用cglib来做代理,实现aop-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
 
 
    上面的两个扫描初始化都是在同一个配置文件中,说要当初始化spring上下文的时候,切面类和controller会在相同的context 
  
2.配置文件中,如果 把切面类和controller 分开,不在同一contex中,会出现什么效果呢?你自己可以亲自实验一下,把
<context:component-scan base-package="com.memcached" />
          把这段配置剪切到 spring-mvc.xml(springmvc的配置文件中)或者其他配置文件中,或者干脆不扫描切面类
          这样子,就会导致anotationAspect.java这个切面类不会拦截。这也验证了上述英文说明的第二点和第三点


好的,我明白了。对于你的问题,我可以这样回答: 利用 SpringMVC 拦截器可以控制 Controller 返回值。拦截器是一种 AOP 的技术,可以在请求处理过程中对请求进行拦截和处理,如校验用户权限、记录请求日志等。在处理 Controller 返回值时,可以通过拦截器对返回值进行处理,如对返回值进行加密、压缩等操作。 具体实现步骤如下: 1. 自定义一个拦截器类并实现 HandlerInterceptor 接口。 2. 在 Spring 配置文件中注册拦截器。 3. 在拦截器中重写 preHandle() 和 postHandle() 方法,分别在请求处理前和请求处理后进行拦截和处理。 4. 在 postHandle() 方法中获取 Controller 返回值并进行处理,如加密、压缩等操作。 下面是一个简单的示例代码: ```java public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理前进行拦截和处理 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 在请求处理后进行拦截和处理 if (modelAndView != null) { // 对返回值进行加密、压缩等操作 } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 在请求完成后进行拦截和处理 } } ``` 在 Spring 配置文件中注册拦截器: ```xml <mvc:interceptors> <bean class="com.example.MyInterceptor"/> </mvc:interceptors> ``` 这样就可以利用 SpringMVC 拦截器控制 Controller 返回值了。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值