Skip to content

Latest commit

 

History

History
57 lines (48 loc) · 2.15 KB

AOP.md

File metadata and controls

57 lines (48 loc) · 2.15 KB

AOP

AOP是Aspect Oriented Programming,即面向切面编程

拦截器

  • @Before:这种拦截器先执行拦截代码,再执行目标代码。如果拦截器抛异常,那么目标代码就不执行了;
  • @After:这种拦截器先执行目标代码,再执行拦截器代码。无论目标代码是否抛异常,拦截器代码都会执行;
  • @AfterReturning:和@After不同的是,只有当目标代码正常返回时,才执行拦截器代码;
  • @AfterThrowing:和@After不同的是,只有当目标代码抛出了异常时,才执行拦截器代码;
  • @Around:能完全控制目标代码是否执行,并可以在执行前后、抛异常后执行任意拦截代码,可以说是包含了上面所有功能。

最佳实践

装配AOP的时候,使用注解是最好的方式(尽量避免使用类似@Around("execution(public update(..))")的语法, 容易误伤,很多不需要被AOP代理的也会被自动代理)

// 定义性能监控的注解
@Target(METHOD)
@Retention(RUNTIME)
public @interface MetricTime {
    String value();
}

// 在需要被监控的关键方法上标注该注解:
@Component
public class UserService {
    // 监控register()方法性能:
    @MetricTime("register")
    public User register(String email, String password, String name) {
        ...
    }
    ...
}

// 定义MetricAspect
@Aspect
@Component
public class MetricAspect {
    @Around("@annotation(metricTime)")
    public Object metric(ProceedingJoinPoint joinPoint, MetricTime metricTime) throws Throwable {
        String name = metricTime.value();
        long start = System.currentTimeMillis();
        try {
            return joinPoint.proceed();
        } finally {
            long t = System.currentTimeMillis() - start;
            // 写入日志或发送至JMX:
            System.err.println("[Metrics] " + name + ": " + t + "ms");
        }
    }
}

无论是使用AspectJ语法,还是配合Annotation,使用AOP,实际上就是让Spring自动为我们创建一个Proxy, 使得调用方能无感知地调用指定方法,但运行期却动态“织入”了其他逻辑,因此,AOP本质上就是一个代理模式。