转载

spring中aop拦截自定义注解不生效

最近小六六自己在项目中遇到的一些真实经历,记录起来关于aop的一些记录

AOP

面向切面编程,Spring AOP  的存在是为了解耦, AOP 可以让一组类共享相同的行为.在 OOP 只能通过继承类和实现接口,来使代码的耦合度增加,且类集成只能为单继承,阻碍更多行为添加到同一类上, AOP 弥补了 OOP 的不足.

Spring 支持 AspectJ  的注解式切面编程.

  • 使用 @AspectJ 声明一个切面
  • 使用 @After 、@Before、@Around 定义建言(advice), 可直接将拦截规则(切点)作为参数.
  • 其中 @After 、@Before、@Around参数的拦截规则为切点(PointCut), 为了使切点复用,可使用 @PointCut 专门定义拦截规则,然后 @After 、@Before、@Around 的参数中调用.
  • 其中符合条件的每一个被拦截处为连接点( JoinPoint)

其实具体来说用法也是很简单的,如下是小六六自己写的代码

spring中aop拦截自定义注解不生效
spring中aop拦截自定义注解不生效

但是当我去使用的时候发下了一些问题,

  • 第一个 我在FeignClient里面使用了这个自定义注解,类似于如下图
spring中aop拦截自定义注解不生效

但是我发现一个问题,这样子做,虽然可以走我们的切面成功,但是切面中获取自定义注解的参数的时候,一直为null.这个就很恼火了,如下

spring中aop拦截自定义注解不生效

为啥会为空呢?原来是因为@FeignClient 这个注解Spring 做了增强,那么你切面的时候,已经是代理类了,所以就拿不到这个内容呢?我去还有这种玩法,行,那我们就换一个玩法,

spring中aop拦截自定义注解不生效
spring中aop拦截自定义注解不生效

小六六就想了个办法,我抽取一个方法出来,这样子 我再另外一个方法再去切面,这样就可以完成了,哈哈 ,我想完美。然而事实并非如此,最后竟然连切面都进不去了。fuck 这个是什么原因呢?

原因分析

其实上面的原因其实很简单,因为我抽取的那个方法用了this,this代表了当前对象,那么我们来看看当前对象是啥就知道了 Controller的

spring中aop拦截自定义注解不生效

ServiceImp

spring中aop拦截自定义注解不生效

很明显了,当前对象是Java对象,而调用的时候是spring 增强的对象,只有spring增强的对象,才有切面的能力。

所以结论就是 方法的调用方,iPaperService,即:是未经过Spring AOP增强的对象实例。所以解决问题的思路就有了,想办法用增强后的HelloService实例来调用!

解决办法

方法一 用Autowired 注入自身的实例

spring中aop拦截自定义注解不生效
spring中aop拦截自定义注解不生效

首先Spring是支持循环依赖的,所以自己注入自己也是可以的,

原文  https://juejin.im/post/5f17d9acf265da22d26ba5be
正文到此结束
Loading...