区别
项目 | JDK 动态代理 | CGLIB 动态代理 |
---|---|---|
代理原理 | 基于接口 (Interface) | 基于字节码生成 (Subclassing) |
实现方式 | 使用 java.lang.reflect.Proxy 类 |
使用 net.sf.cglib.proxy.Enhancer 类 |
被代理类要求 | 必须实现一个或多个接口 | 可以代理没有实现接口的类,可以是普通类 |
性能 | 由于通过反射调用接口方法,性能稍差 | 通过生成子类并调用父类方法,性能较好 |
代理类生成方式 | 在运行时动态生成代理类 | 在运行时通过生成子类并字节码增强 |
方法调用的灵活性 | 只代理接口中的方法 | 可代理类中的所有方法,包括私有方法,但不能代理 final 方法 |
侵入性 | 需要被代理类实现接口 | 不需要被代理类实现接口,非侵入式 |
使用复杂度 | 较低,JDK 自带,配置简单 | 较高,需要引入第三方库,可以配置较多的代理行为 |
适用场景
代理技术 | 适用场景 |
---|---|
JDK 动态代理 | 适用于需要代理实现了接口的类,且无需代理性能特别高的情况 |
CGLIB 动态代理 | 适用于需要代理没有实现接口的普通类,且需要较高的代理性能 |
示例代码
JDK 动态代理示例:
1 // 定义接口 2 interface SampleInterface { 3 void test(); 4 } 5 6 // 实现接口的原始类 7 class SampleClass implements SampleInterface { 8 @Override 9 public void test() { 10 System.out.println("Hello World"); 11 } 12 } 13 14 // 自定义 InvocationHandler 15 class MyInvocationHandler implements InvocationHandler { 16 private final Object target; 17 18 public MyInvocationHandler(Object target) { 19 this.target = target; 20 } 21 22 @Override 23 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 24 System.out.println("Before method call"); 25 Object result = method.invoke(target, args); 26 System.out.println("After method call"); 27 return result; 28 } 29 } 30 31 public class JdkProxyExample { 32 public static void main(String[] args) { 33 SampleClass original = new SampleClass(); 34 35 SampleInterface proxyInstance = (SampleInterface) Proxy.newProxyInstance( 36 original.getClass().getClassLoader(), 37 original.getClass().getInterfaces(), 38 new MyInvocationHandler(original) 39 ); 40 41 proxyInstance.test(); 42 } 43 }JDK 动态代理示例
CGLIB 动态代理示例:
1 import net.sf.cglib.proxy.Enhancer; 2 import net.sf.cglib.proxy.MethodInterceptor; 3 import net.sf.cglib.proxy.MethodProxy; 4 5 import java.lang.reflect.Method; 6 7 class SampleClass { 8 public void test() { 9 System.out.println("Hello World"); 10 } 11 } 12 13 public class CglibExample { 14 public static void main(String[] args) { 15 Enhancer enhancer = new Enhancer(); 16 enhancer.setSuperclass(SampleClass.class); 17 18 enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> { 19 System.out.println("Before method call"); 20 Object result = proxy.invokeSuper(obj, args1); 21 System.out.println("After method call"); 22 return result; 23 }); 24 25 SampleClass proxy = (SampleClass) enhancer.create(); 26 proxy.test(); 27 } 28 }CGLIB 动态代理示例
总结:选择哪种代理技术取决于具体的场景和需求。JDK 动态代理简单而直接,适用于接口代理;CGLIB 动态代理则功能强大,适用于需要高性能和类代理的场景
标签:场景,JDK,代理,接口,proxy,CGLIB,动态,public From: https://www.cnblogs.com/auv2009/p/18516370