• Spring的Aspect切面类不能拦截Controller中的方法


    根本原因在于<aop:aspectj-autoproxy />这句话是在spring的配置文件内,还是在springmvc的配置文件内。如果是在spring的配置文件内,则@Controller中的方法不会被拦截。

    看一下applicationContext.xml中bean扫描的配置,此处排除了controller层的扫描:

    <context:component-scan base-package="com">
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    <context:component-scan base-package="icom">
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    看一下springmvc-servlet.xml中bean扫描的配置,此处排除了service层的扫描:

    <context:component-scan base-package="com">
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
    </context:component-scan>
    <context:component-scan base-package="icom">
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
    </context:component-scan>

    所以要拦截哪层的类中的方法,就应该在相应的配置文件中添加<aop:aspectj-autoproxy />

    解决办法:

    注释掉applicationContext.xml中的<aop:aspectj-autoproxy />,在springmvc-servlet.xml中配置:

    <bean id="aspectBean" class="icom.axx.action.AopAspect" />
    <aop:aspectj-autoproxy />

    另外,不要忘记增加:

    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation=
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

    除非整个web应用中只配置一个<component-scan>,且这个base-package同时包含了所有要扫描的包时,才会出现Controller的bean的初始化早于其它bean的情况。

    如果是Spring的Bean扫描文件和spring-mvc-servlet中的的bean扫描文件是分开的,那么就是先扫描Spring的Bean;最后才扫描spring-mvc的bean。因为Spring的Bean是由监听器ContextLoaderListener负责扫描装载的,而spring-mvc的servlet-config.xml中配置的<component-scan>bean处于Servlet级别的,监听器的启动顺序自然要早于Servlet的启动顺序。

    出现AOP切不到Controller的真正原因在于<aop:aspectj-autoproxy/>这句的位置。

    更具体的原因:假如你在两份配置文件:spring-config.xml springmv-servlet.xml中都配置了扫描全部的包,那么你会发现所有的Bean都被先后实例化了一次,先spring-config.xml ;后 springmv-servlet.xml。两者实例化的Bean分别放在了父子容器中。

    第一次初始化AController时,是在spring-config.xml 中(里面有aspectj-autoproxy配置),这时,这个AControllerBean就会被初始化为AOP代理对象,存在父容器中。

    然后 springmv-servlet.xml中并没有aspectj-autoproxy,所以AControllerBean就是一个普通Bean,存在子容器中,没有被AOP代理。

    当URL访问Controller时,就会用到子容器中的普通ControllerBean,所以AOP切不到。

    所以在项目开发中,最好是明确职责边界,Spring-application-config.xml只负责核心的Bean初始化;springmvc-servlet-config.xml只负责和mvc相关的bean:比如Controller、HandlerMapping、HandlerAdapter.

    参考:

    https://www.cnblogs.com/Frank-Hao/p/5787813.html

     
  • 相关阅读:
    [NOI2004]cashier 郁闷的出纳员
    [HNOI2004]宠物收养所
    [HNOI2002]营业额统计
    浅谈算法——莫比乌斯反演
    浅谈算法——splay
    [POI2006]Tet-Tetris 3D
    BZOJ2733 [HNOI2012]永无乡 【线段树合并】
    UOJ279 【UTR #2】题目交流通道
    UOJ278 【UTR #2】题目排列顺序
    POJ2761 Feed the dogs
  • 原文地址:https://www.cnblogs.com/xyhero/p/65e3329f90083e4f28cae249486e8705.html
Copyright © 2020-2023  润新知