如何定义匹配未重写接口默认方法的子类方法的切入点(兼容测试)
兼容Spring Boot运行与单元测试的切入点方案
问题核心原因
Spring Boot里的bean(foo3)切入点依赖Spring容器的bean名称标识,但手动用AspectJProxyFactory创建代理时,对象没纳入Spring容器管理,所以这个切入点直接失效。之前试的target(Foo3) && execution(* Foo.m1(..))无效,大概率是没写全限定类名,或是对默认方法的连接点匹配逻辑理解有偏差。
可行的切入点定义
用下面这个切入点,能同时兼容Spring Boot运行环境和AspectJProxyFactory手动代理的单元测试场景:
@Pointcut("target(com.yourpackage.Foo3) && execution(* com.yourpackage.Foo.m1(..))")
逻辑说明:
target(com.yourpackage.Foo3):不管对象是否在Spring容器里,只要代理的目标实例是Foo3,就会命中这个条件。execution(* com.yourpackage.Foo.m1(..)):精准匹配Foo接口的m1默认方法。因为Foo3没重写m1,调用它的m1时实际执行的是接口默认方法,所以这个execution表达式能准确匹配;而Foo1、Foo2重写了m1,它们的m1方法execution签名是自身类的方法,不会被这个表达式命中,自然不会被拦截。
单元测试代理创建示例
手动创建代理时,要确保目标对象是Foo3:
Foo3 target = new Foo3(); AspectJProxyFactory factory = new AspectJProxyFactory(target); factory.addAspect(YourAspect.class); Foo proxy = factory.getProxy(); proxy.m1(); // 此时切面会正常拦截该调用
备选简化方案
如果上面的切入点还有问题,可试试更简洁的版本:
@Pointcut("target(com.yourpackage.Foo3) && execution(* *.m1(..))")
这个表达式会匹配Foo3实例上所有叫m1的方法,Foo1、Foo2的m1因为目标对象不是Foo3,会被自动排除,同样能满足需求。
内容的提问来源于stack exchange,提问作者Lofri97
相关产品推荐
相关产品推荐

