SpringMVC中配aop拦截不生效,咋回事

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC中配aop拦截不生效,咋回事相关的知识,希望对你有一定的参考价值。

参考技术A   最近由于项目原因,在Spring+SpringMVC+Mybatis的环境中,增加对controller或是service的日志监控,在网上搜了半天,按照SpringAop的配置出不了结果,在按照网上的各种配置改……,各种头疼中,无意中看到摸个高手写的一段文字突然,感觉很有意思,就这样莫名其妙的解决了。回头看,我去,别人都写好了,我们配置都不会配置,悲哀…,这就是我对各种框架一知半解,甚至不知道的结果。
  首先对入口文件,web.xml分析:
  还有一点,我们可以查到,加载这连个配置文件的累分别是:spring(applicationContext),SpringMVC(webApplicationContext)(希望没记错,记错了自己对应修改)
  第一步,要明确,我们是在SpringMVC上aop监测,那么所有的报扫描注入都在SpringMVC的配置文件中完成,不要再spring的配置文件中完成,不然在开启代理后,发现还是没有起到任何作用。(当然,aopalliance-1.0.jar,aspectjweaver-1.8.6.jar这两个jar包不可缺少)
  第二步,在SpringMVC的配置文件中开启它的代理模式:<aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy>
  第三步,进行aop监测相关方法的类的编写
  最后就是一个小技巧,就是先测pointcut表达式的具体到某一个具体函数,成功后,在用.*来代替,在测,知道成功完成为止!!!!!
  希望对大家有帮住,也希望有大牛深入剖析其中的原理。有看到的同学请给我转个链接,谢谢。
参考技术B spring整合事物使用aop的,你可以参考一下
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="create*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="select*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice"
pointcut="execution(* com.service.*.*(..))" />
</aop:config>
参考技术C 首先我的aop切面类文件路径有问题,后来移到了logic下的util包中; <aop:aspectj-autoproxy proxy-target-class="true"/> 放在spring-mvc.xml中即可。 ...

Spring 嵌套方法AOP不生效问题

问题描述, 如下Abc定义为一个Bean, b()方法添加@TargetDatasource,定义切面DynamicDataSourceAspect,期望:调用a()方法,b()方法上的AOP拦截能生效。实际不生效。

@Service

public class Abc {

public void a(){
b();
}

@TargetDatasource(value=abc) public void b(){
} }

 

AOP代码:

@Order(-1)
@Component
@Slf4j
@Aspect
public class DynamicDataSourceAspect {

  /**
   * set data source value.
   */
  @Before(value = "@annotation(targetDataSource)", argNames = "targetDataSource")
  public void setDataSource(TargetDataSource targetDataSource) {
    if (targetDataSource != null && targetDataSource.value() != null) {
      log.info("Databse value: {}", targetDataSource.value());
      DynamicDataSourceHolder.set(targetDataSource.value());
    }
  }

  /**
   * clear data source value.
   */
  @After(value = "@annotation(targetDataSource)", argNames = "targetDataSource")
  public void clearDataSource(TargetDataSource targetDataSource) {
    DynamicDataSourceHolder.clear();
  }
}

 

问题分析:

我们都知道Spring aop有两种实现方式,基于Interface生成代理和cglib生成代理。上面的例子中,当调用a()方法时,调用者拿到的是Abc的代理类,即增强类。如果a()方法上有@TargetDatasource注解,拦截会生效。然而,在a()方法里调用b(),b方法上的拦截不会生效。原因是因为a()调用b(), 用的是b()方法的目标类,而不是代理类,所以拦截不生效。

 

解决方法:

1. 重构代码, 把b()方法移到一个Bean里面。

2. 调整a()方法如下:

@Service

public class Abc {

public void a(){
   ((Abc)AopContext.currentProxy()).b();
}

@TargetDatasource(value=abc)
public void b(){
}
}

 

Sping 官方解释 - https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop 






以上是关于SpringMVC中配aop拦截不生效,咋回事的主要内容,如果未能解决你的问题,请参考以下文章

nginx重启不生效是咋回事

springmvc里面自定义注解实现aop,controller层里面注解一直不生效,但是注解放在service层又可以??

Spring AOP中@Aspect拦截介绍(一)

spring AOP 拦截器实现问题

Spring 嵌套方法AOP不生效问题

SpringBoot 基础系列接口上注解 AOP 拦截不到场景兼容实例演示