Java 动态代理 & AOP

概述

AOP => Aspect Oriented Programming => 面向切面编程 => 关注一个统一的切面
OOP => Object Oriented Programming => 面向对象编程

AOP 适用于需要统一处理的场景

  • 日志
  • 缓存
  • 鉴权

OOP 处理上述场景 => Decorator 装饰器模式

AOP

一般使用 Interface => 使用类,如果类里面有成员变量,继承类的时候都会拿到一份成员变量,有可能是没有用的,浪费空间 => interface 更加灵活,不会受到抽象类的限制(单根继承)

JDK 动态代理实现 AOP

  • java.lang.reflect.InvocationHandler
  • java.lang.reflect.Proxy.newProxyInstance => 只有被代理的接口,未来被调用的时候才会进入到 InvocationHandler 的 invoke 方法中
  • 优点:方便,不需要依赖任何第三方库
  • 缺点:功能受限,只适用于接口
    // TODO: example

CGLIB | ByteBuddy 字节码生成实现 AOP

  • 优点:强劲,不受接口限制
  • 缺点:需要引用额外的第三方类库 + 不能增强 final 类 & final method & private method => 使用继承方式

Spring 中使用 AOP

spring-boot-starter-aop dependency => 默认使用 JDK 动态代理
CGLIB config => application.properties => spring.aop.proxy-target-class=true

  • @Aspect => 声明一个切面
  • @Configuration => 告知 Spring 当前类是用于生成和 Spring 有关的配置
  • @Before => 在开始一个方法之前
  • @After => 在结束一个方法之后
  • @Around => 将方法包裹起来 => @Around("@annotation(xxx.anno.Cache)") => 参数 org.aspectj.lang.ProceedingJoinPoint

// TODO: Spring boot AOP 实现 cache 缓存

知识点

  1. AOP 和 Spring 是不同的东西 => AOP 更多的使用场景是在 Spring 中,Spring 使得 AOP 变得更加强劲
  2. Spring 是如何切换 JDK 动态代理和 CGLIB 的 => 默认是 JDK 动态代理 => CGLIB 配置 => spring.aop.proxy-target-class=true
  3. Redis + Serializable Error => 找到拦截方法 => Redis 默认的序列化的库是 java.io.Serializable
© 版权声明

相关文章

暂无评论

none
暂无评论...