Spring Boot中DefaultPointcutAdvisor失效问题咨询
我来帮你梳理下DefaultPointcutAdvisor失效的常见排查点,结合你给出的代码片段,咱们一步步来排查:
确认AOP功能是否开启
你得确保Spring项目中已经添加了@EnableAspectJAutoProxy注解,不管是标注在你的AspectAutoConfig配置类上,还是标注在Spring Boot的启动类上都可以。如果没加这个注解,Spring不会启动AOP代理机制,你的Advisor自然不会生效。检查AnnotationMatchingPointcut的参数是否匹配你的注解场景
你代码里用了new AnnotationMatchingPointcut(MyLog.class, true),这里的第二个参数true表示只匹配类上标注了@MyLog的Bean。如果你的@MyLog注解是标注在方法上的,那这里应该传false,或者更清晰的写法是用AnnotationMatchingPointcut.forMethodAnnotation(MyLog.class)来专门匹配方法级的注解。
另外还要检查@MyLog注解本身的定义:必须加上@Retention(RetentionPolicy.RUNTIME)(保证运行时可见),如果要支持类和方法上都能标注,还要加上@Target({ElementType.TYPE, ElementType.METHOD})。验证MethodLogInterceptor的实现是否正确
你的拦截器MethodLogInterceptor必须实现Spring的MethodInterceptor接口,而且在invoke方法里一定要调用invocation.proceed(),否则目标方法不会执行,看起来就像Advisor没生效。比如正确的实现应该是这样:public class MethodLogInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { // 这里写你的日志逻辑,比如打印方法信息 System.out.println("开始执行方法:" + invocation.getMethod().getName()); Object result = invocation.proceed(); // 必须调用这个方法让目标方法执行 System.out.println("方法执行结束"); return result; } }如果你的拦截器里漏掉了
invocation.proceed(),或者逻辑有错误,都会导致日志不输出或者目标方法不执行。确认目标类是Spring容器中的Bean
Spring AOP只能代理被Spring管理的Bean,如果你要拦截的类是用new关键字手动创建的,而不是通过@Component、@Service等注解注册到Spring容器的,那Advisor无法作用到这个类上。检查代理类型是否适配
Spring AOP默认用JDK动态代理,这种代理只针对实现了接口的类。如果你的目标类没有实现任何接口,那需要在@EnableAspectJAutoProxy注解里加上proxyTargetClass = true,启用CGLIB代理,这样才能为目标类创建代理对象,Advisor才能生效。确认Advisor的Bean被正确加载
你的AspectAutoConfig类加了@Configuration,要确保这个配置类在Spring的扫描范围内(比如启动类的@ComponentScan能覆盖到这个类的包)。如果配置类没被Spring加载,那myLogAnnotation这个Advisor Bean就不会被注册,自然不会生效。检查Order顺序是否影响执行
你设置了myLogAdvisor.setOrder(Ordered.HIGHEST_PRECEDENCE + 500),这个优先级比较高,但如果有其他优先级更高的Advisor或者Aspect拦截了方法,并且修改了执行流程(比如抛出异常、跳过执行),可能会影响你的日志拦截。可以先把Order调整为默认值(不设置Order的话默认是最低优先级),看看是否能正常生效。
内容的提问来源于stack exchange,提问作者Tonney Bing

