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

来源:互联网 发布:淘宝客返利返到哪里 编辑:程序博客网 时间:2024/06/10 06:29

 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配置文件中,如下两个配置证明了,上述英文说明的第一点
<span style="color:#3366ff;">         //这个扫描配置,com.yt下面所有的包都扫描,但是</span><span style="color:#ff9966;">没有扫描</span><span style="line-height: 20.7999992370605px; font-family: Verdana, Arial, Helvetica, sans-serif;"><span style="color:#ff9966;">com.memcached这个包下的切面类</span></span><pre name="code" class="html" style="color: rgb(51, 102, 255); font-size: 13px; font-weight: bold; line-height: 20.7999992370605px;">         <context:component-scan base-package="com.yt.*" />
<!--拦截controller层的方法,需要配置注解扫描 切面类(其实切面类就是anotationAspect.java),这里必选配置启动扫描 --> <context:component-scan base-package="com.memcached" />
<span style="color:#3366ff;"></span><pre name="code" class="html" style="font-size: 13px; font-weight: bold; line-height: 20.7999992370605px;">          <!--注意不要忘记,使用cglib来做代理,实现aop-->
<pre name="code" class="html">          <aop:aspectj-autoproxy proxy-target-class="true"/>

   上面的两个扫描初始化都是在同一个配置文件中,说要当初始化spring上下文的时候,切面类和controller会在相同的context
  
2.配置文件中,如果 把切面类和controller 分开,不在同一contex中,会出现什么效果呢?你自己可以亲自实验一下,把
<span style="color:#3366ff;">      <context:component-scan base-package="com.memcached" /></span>
          把这段配置剪切到 spring-mvc.xml(springmvc的配置文件中)或者其他配置文件中,或者干脆不扫描切面类
          这样子,就会导致anotationAspect.java这个切面类不会拦截。这也验证了上述英文说明的第二点和第三点


0 0
原创粉丝点击