代码之家  ›  专栏  ›  技术社区  ›  SunLiWei

Spring Boot AOP不适用于AfterThrow

  •  1
  • SunLiWei  · 技术社区  · 9 年前
    package test.aop;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.velocity.VelocityAutoConfiguration;
    import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
    
    @Component
    @Aspect
    class LoggingMonitor {
    
        @AfterThrowing(
                pointcut = "execution(* test.aop..foo(..))",
                throwing = "error")
        public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {
            System.out.println(joinPoint);
        }
    }
    
    @Service
    class MyBean {
        void foo() {
            throw new RuntimeException("run error");
        }
    }
    
    @SpringBootApplication
    public class App {
        @Autowired
        MyBean myBean;
    
        @Bean
        CommandLineRunner runner() {
            return r -> {
                System.out.println("Run");
                myBean.foo();
            };
        }
    
        public static void main(String[] args) {
            SpringApplication.run(App.class);
        }
    }
    

    我不明白为什么上面的代码不起作用,但当我将切入点更改为“*.springframework.boot.CommandLineRunner.run(..)”时,它起作用了。

    1 回复  |  直到 9 年前
        1
  •  2
  •   Sean Patrick Floyd    9 年前

    Spring AOP仅适用于公共方法。将您的方法公开,或还原为AspectJ。

    由于Springs AOP框架基于代理的特性 根据定义,方法不会被拦截,JDK代理也不会被拦截 (如果不适用)也不适用于CGLIB代理(如果适用 在技术上是可能的,但对于AOP目的来说是不推荐的)。作为一个 因此,任何给定的切入点都将与公共方法相匹配 只有如果您的拦截需要包括受保护的/私有的方法或 即使是构造函数,也可以考虑使用Spring驱动的本机AspectJ 编织而不是基于Springs代理的AOP框架。这 使用不同的 所以一定要熟悉编织 在做出决定之前,请先。

    Source