什么是AOP

  • Aspect-Oriented Programming 面向切面编程
  • 相对于OOP
  • AOP是面向切面编程
    • 关注的不是对象本身,而是一个统一的切面

AOP适用的场景

  • 需要统一处理的场景
    • 日志
    • 缓存
    • 鉴权
  • 如果不是用AOP,而是用OOP来做
    • 装饰器模式

Decorator pattern

  • 动态地为一个对象增加功能,但是不改变其结构
  • 本质上是一个“包装”
  • 被包装的类,要被包装的每个方法,在装饰器(类)都要写一次
    • 用AOP解决这个问题

AOP的实现

1. JDK动态代理

  • Proxy
    ```java MyService myService = (MyService) Proxy.newProxyInstance( service.getClass().getClassLoader(), new Class[]{MyService.class}, new LogProxy(service) );

// LogProxy public class LogProxy implements InvocationHandler { MyService delegate;

  1. public LogProxy(MyService delegate) {
  2. this.delegate = delegate;
  3. }
  4. @Override
  5. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  6. System.out.println(method.getName() + "is invoked");
  7. Object value = method.invoke(delegate, args);
  8. System.out.println(method.getName() + "is finished");
  9. return value;
  10. }

} ```

2. 字节码生成

  • CGLIB/ByteBuddy字节码生成
    • 原理都是通过字节码动态生成一个enhance类
  • 优点:强大,不受接口的限制
  • 缺点:
    • 需要引用额外的第三方类库
    • 使用继承的方式,不能增强final类,final/private方法(JDK动态代理也有这个缺陷)

AOP与Spring

  • 在Spring中使用AOP实现Redis缓存
  • Spring是如何切换JDK动态代理和CGLIB的?
    • 设置 spring.aop.proxy-target-class=true
  • @Aspect 声明切面类