适用场景:
- Spring工厂
适用场景:
- 可插拔式服务
适用场景:
适用场景:
- 适用于框架的骨架设计
适用场景:
- 应用场景与MQ类似
适用场景:
- 适用于Spring的单例Bean原理
适用场景:
适用场景:
- jdk动态代理
- 适用于feign客户端代理原理
- 使用于mybatis之mapper代理原理
静态代理实现方式:
动态代理实现方式:
cglib代理实现方式:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>${cglib.version}</version>
</dependency>
从 JDK 1.8 升级到 JDK 17 之后,cglib报异常:
Caused by: net.sf.cglib.core.CodeGenerationException:
java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @4361bd48
解决方案: 在 java 命令后添加额外的参数 --add-opens java.base/java.lang=ALL-UNNAMED
cglib注意小心使用!
// 我们可能会习惯了在jdk动态代理的h.invoke方法中,执行method.invoke(target, args);target是传入h内部的目标对象
// 但是注意在cglib的intercept方法签名处,第一个参数是proxy – "this", the enhanced object, 是代理对象即this
// 因此下面这种给method.invoke(proxy, args);传入this将会出现死循环调用
try {
//原方法执行方式invokeSuper:
Object invokeValue1 = methodProxy.invokeSuper(proxy, args);//执行被代理方法
System.out.println("原方法执行方式1:methodProxy.invokeSuper(target, args);的结果:"+invokeValue1);
// 我们可能会习惯了在jdk动态代理的h.invoke方法中,执行method.invoke(target, args);,其中target是传入h内部的目标对象
// 但是注意在cglib的intercept方法签名处,第一个参数是proxy – "this", the enhanced object, 是代理对象即this
// 因此下面这种给method.invoke(proxy, args);传入this将一定会出现死循环调用
// method.setAccessible(true);
// Object invokeValue2 = method.invoke(proxy, args);
// System.out.println("原方法执行方式2:method.invoke(target, args);的结果:"+invokeValue2);
} catch (Throwable e) {
throw new RuntimeException(e);
}
适用场景:
- 方法增强
适用场景:
- 类似于重载方法
适用场景:
- builder工厂
适用场景:
- 适用于AOP链式执行
- 适用于Mybatis的二级缓存
实现方式:
- 基于工厂的责任链
- 基于建造者的责任链
- 基于泛型和工厂的责任链,将数据对象和工厂都定义为泛型,使得责任链更加通用,
- 基于泛型和建造者的责任链,将数据对象和建造器都定义为泛型,使得责任链更加通用
适用场景:
- jdk Integer/Long数据池
- 自定义数据库连接池:数组/集合对象
- springioc容器:Map集合
适用场景:
适用场景:
- 封装内部的调用细节
- 业务二次封装缓存组件
- 业务二次封装消息组件
适用场景:
适用场景:
适用场景:
- 如iterator
适用场景:
- spring-statemachine
适用场景:
适用场景:
适用场景: