spring 使用@aspect 不生效问题

B类标注了@aspect及@Component,其中的b方法使用@Around拦截了A类的a方法,同时A类的a方法添加了@Transactional注解。当C类的c方法调用A类的a方法后,B类的b方法并不会拦截到a方法的执行,这种情况的原因是啥?如何解决

C类的c方法调用A类的a方法,你这C类中的A类,是注入进去的吗?最好把相关代码复制上来看看。

对,A类是一个service类,在C类中是通过@resource注解注入的,并且C类也是添加了@service注解的一个service类

没有代码,很难猜。



第一个和第二个图是C类中注入了A类并且调用了A类的a方法,第三个图是B类


再补充一个图,这个是A类a方法的实现类

我感觉像是你的Aop没有开启成功。你仔细看看DEBUG日志。还有就是你是从哪里看出来所谓的“B类的b方法并不会拦截到a方法的执行”。

第二个截图中的代码执行后(也是就C类调用完A类的a方法),B类的@around方法没有执行,根据这个判断出来没生效的

我怀疑你的Aop配置没有生效,你添加了注解@EnableAspectJAutoProxy 注解没有?

执行A类的其他方法是可以正常被拦截到的,springboot项目默认是开启的吧

兄弟,还有啥思路吗

就这些信息的话,我没啥思路。如果可以的话,你把项目发布到Github上,我可以clone下来帮忙看看。

好,我写个例子到时候@你

你好,有github访问不了 我传到码云上了 麻烦协助看一下,demo例子 中访问test1 调用save方法不会被拦截,访问test2 调用update方法可以正常被拦截

我看了一下,把save方法放到XXXServiceImpl 就可以被切到。至于为什么父类实现方法不能被代理我也不清楚现在。

我在网上也查看了一些资料,好像普遍都有这个说法:

execution() 匹配父类的某个方法, 那么aop对其子类的这个方法都有效, 即使子类重写了父类的方法扔有效

execution() 匹配子类的某个方法, 如果这个方法是继承自父类的, 那么只有当子类重写了父类的这个方法, aop才对这个方法有效; 否则无效(即使execution不是通过通配符, 而是明确指定子类某个继承方法, 也是无效的)

可以考虑使用 within 表达式,这种表达式可以代理指定接口其子类的实现的所有方法。

@Around("within(cn.com.test.IService+)")
public Object aopTest(ProceedingJoinPoint p) throws Throwable {
	System.out.println(p.getSignature().getName() +  ": 执行前");
	Object ret = p.proceed();
	System.out.println(p.getSignature().getName() +  ": 执行后");
	return ret;
}

执行日志

save: 执行前
execute save
save: 执行后
upate: 执行前
around .XXXService.upate
execute update
upate: 执行后

特地留意了下这个问题。我也拉代码看了一下。在 AopUtils.canApply 的方法中看出 会选择出一个最佳实现方式作为连接点。而 最佳连接点是serviceImpl.save ,从此连接点中查找候选匹配,是无法找到XXXService.save的,因为serviceImpl.save和XXXService.save就没有任何关系,它是实现的IService.save。所以就无法和切点相匹配。如果你的serviceImpl.save 是 实现的XXXService.save 则能够找到切点。同理,你around换成Iservice也可以。

1 个赞