大家好我是Java1234_小锋老师。JDK动态代理和CGLIB动态代理的区别在Java中动态代理是一种在运行时创建对象的技术常用于实现AOP面向切面编程。动态代理可以将横切关注点如日志、事务等与业务逻辑分离。Java提供了两种主要的动态代理技术JDK动态代理和CGLIB动态代理。下面我们将比较这两种技术并给出示例代码来说明它们的用法。一、JDK动态代理JDK动态代理是Java内置的一种代理机制它要求被代理的类实现一个或多个接口。java.lang.reflect.Proxy类提供了创建代理实例的方法。使用JDK动态代理需要遵循以下步骤创建一个接口及其实现类。创建一个InvocationHandler来处理方法调用。使用Proxy类生成代理对象。示例代码importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;// 定义接口interfaceHelloService{voidsayHello(Stringname);}// 实现接口classHelloServiceImplimplementsHelloService{publicvoidsayHello(Stringname){System.out.println(Hello, name);}}// 创建InvocationHandlerclassMyInvocationHandlerimplementsInvocationHandler{privateObjecttarget;publicMyInvocationHandler(Objecttarget){this.targettarget;}OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println(Before method: method.getName());Objectresultmethod.invoke(target,args);System.out.println(After method: method.getName());returnresult;}}// 使用JDK动态代理publicclassJDKDynamicProxyExample{publicstaticvoidmain(String[]args){HelloServicehelloServicenewHelloServiceImpl();HelloServiceproxyInstance(HelloService)Proxy.newProxyInstance(helloService.getClass().getClassLoader(),helloService.getClass().getInterfaces(),newMyInvocationHandler(helloService));proxyInstance.sayHello(World);}}二、CGLIB动态代理CGLIBCode Generation Library是一个强大的、高性能的代码生成库可以为没有实现接口的类创建代理。CGLIB通过继承目标类并重写其方法来实现代理。由于这种方式对类进行了修改因此CGLIB不能为final类或final方法创建代理。示例代码importorg.springframework.cglib.proxy.Enhancer;importorg.springframework.cglib.proxy.MethodInterceptor;importorg.springframework.cglib.proxy.MethodProxy;// 目标类classHelloService{publicvoidsayHello(Stringname){System.out.println(Hello, name);}}// 创建MethodInterceptorclassMyMethodInterceptorimplementsMethodInterceptor{OverridepublicObjectintercept(Objectobj,java.lang.reflect.Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{System.out.println(Before method: method.getName());Objectresultproxy.invokeSuper(obj,args);// 调用目标方法System.out.println(After method: method.getName());returnresult;}}// 使用CGLIB动态代理publicclassCGLIBDynamicProxyExample{publicstaticvoidmain(String[]args){EnhancerenhancernewEnhancer();enhancer.setSuperclass(HelloService.class);enhancer.setCallback(newMyMethodInterceptor());HelloServiceproxyInstance(HelloService)enhancer.create();proxyInstance.sayHello(CGLIB World);}}三、比较接口要求JDK动态代理要求目标对象实现接口代理类是由Proxy.newProxyInstance(...)生成的。CGLIB动态代理不需要目标对象实现接口直接对子类进行代理。性能JDK动态代理由于是反射机制性能略低。CGLIB动态代理性能较高因为它使用字节码生成。适用场景JDK动态代理适用于需要面向接口的设计场景。CGLIB动态代理适用于没有接口的类或需要代理final类需要注意CGLIB无法代理final方法。使用便利性JDK动态代理需要创建接口和实现类较为繁琐。CGLIB动态代理使用简单不需创建接口。总结来说选择JDK动态代理或CGLIB动态代理取决于具体的应用场景以及对性能、设计的需求。如果目标类实现了接口并且符合JDK动态代理的使用条件可以优先选择JDK动态代理如果没有接口或者需要代理的类较多则可以考虑使用CGLIB动态代理。