2015-09-17 85 views
1
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); 
    } 
} 

我不明白,为什么上面没有工作,但代码时,我改变了我的切入点,以“* org.springframework.boot.CommandLineRunner.run(..)”,它作品。春天引导AOP不工作的AfterThrow

回答

2

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

由于Spring的AOP框架的基于代理的性质,保护 方法是通过定义不拦截,既不是JDK代理 (其中,这是不适用),也不是CGLIB代理(如使用 技术上可能但不推荐用于AOP目的)。作为 的后果,任何给定的切入点将仅与公共方法 匹配!如果您的拦截需求包括受保护/私有方法或构造函数,请考虑使用Spring驱动的本机AspectJ 而不是Spring的基于代理的AOP框架。这 构成不同的模式的AOP用法与不同的 的特点,所以一定要先做好编织 先熟悉,然后再作出决定。

Source