软件编程
位置:首页>> 软件编程>> java编程>> Java JDK与cglib * 有什么区别

Java JDK与cglib * 有什么区别

作者:王佑辉  发布时间:2023-07-23 08:10:15 

标签:Java,JDK,cglib, ,

一、说明

1.spring aop中的 * 主要有两种方式,jdk * 和cglib *

2.从实现接口、继承父类的角度讨论区别

3.从限制角度讨论区别

4.从性能上讨论区别

二、区别

1.jdk * 只提供实现接口的目标类代理,不支持没有实现接口的目标类的代理。如果目标类没有实现接口,只能用cglib代理

2.jdk * 会在运行时为目标类生成一个 * 类$proxy*.class。cglib的底层是通过ASM在运行时动态生成目标类的子类,还会有其它类

3. jdk * 的代理类实现了目标类实现的接口,并且会实现接口所有方法来代码增强。cglib * 会重写父类所有的方法来代码增强

4.jdk * 调用时先去调用处理类进行增强,再通过反射的方式调用目标类的方法。cglib * 调用时先通过代理类进行增强,再直接调用父类对应的方法进行调用目标方法

5.jdk * 如果目标类未实现接口则无法代理,cglib是通过继承的方式来 * ,若目标类被final关键字修饰,则无法使用cglib做 *

6.性能上:在老版的jdk,jdk代理生成的类速度快,通过反射调用慢,cglib是jdk代理速度的10倍左右,jdk在版本每次升级都会有很大的性能提升,cglib停滞不前,jdk7 8的 * 性能在1万次实验中比cglib要快20%左右

三、代码示例

3.1 静态代理

package com.proxy.staticproxy;
public interface SellTicket {
   void sell();
}
package com.proxy.staticproxy;
public class TrainStation implements SellTicket{
    @Override
    public void sell() {
        System.out.println("火车站售票");
    }
}
package com.proxy.staticproxy;
public class ProxyPoint implements SellTicket{
   //声明火车类对象
   private TrainStation trainStation = new TrainStation();
   @Override
   public void sell() {
       System.out.println("代售点收取服务费");
       trainStation.sell();
   }
   public static void main(String[] args) {
       ProxyPoint proxyPoint = new ProxyPoint();
       proxyPoint.sell();
   }
}

3.2 jdk *

package com.proxy.jdkproxy;
import com.proxy.staticproxy.SellTicket;
import com.proxy.staticproxy.TrainStation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
   private TrainStation trainStation = new TrainStation();
   public SellTicket getProxyPoint() {
       /**
        * ClassLoader loader: 类加载器,用于加载代理类。可以通过目标对象获取类加载器
        * Class<?>[] interfaces: 代理类实现的接口的字节码对象
        * InvocationHandler h: 代理对象的调用处理程序
        */
       SellTicket sellTicket = (SellTicket)Proxy.newProxyInstance(trainStation.getClass().getClassLoader(), trainStation.getClass().getInterfaces(),
               new InvocationHandler() {
                   /**
                    * @param proxy 代理对象 proxyObject是同一个对象,在invoke方法中基本不用
                    * @param method 对接口中的方法进行封装的method对象
                    * @param args 调用方法的实际参数
                    * @return 方法返回值
                    * @throws Throwable
                    */
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    // 代码增强
                       System.out.println("代理点收取服务费");
                       Object object = method.invoke(trainStation, args);
                       return object;
                   }
               });
       return sellTicket;
   }
   public static void main(String[] args) {
       ProxyFactory proxyPoint = new ProxyFactory();
       SellTicket sellTicket = proxyPoint.getProxyPoint();
       sellTicket.sell();
   }
}

3.3 cglib *

<!-- 引入cglib依赖包-->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>
package com.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ProxyFactory implements MethodInterceptor {
   private TrainStation trainStation = new TrainStation();
   public TrainStation getTrainStation(){
       //创建Enhancer对象,类似于JDK代理中的Proxy类
       Enhancer enhancer = new Enhancer();
       //设置父类的字节码对象
       enhancer.setSuperclass(TrainStation.class);
       //设置回调函数
       enhancer.setCallback(this);
       //创建代理对象
       TrainStation trainStation = (TrainStation)enhancer.create();
       return trainStation;
   }
   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
   // 代码增强
       System.out.println("代售点收取服务费用");
       Object obj = method.invoke(trainStation, objects);
       return obj;
   }
   public static void main(String[] args) throws Exception {
       ProxyFactory proxyFactory = new ProxyFactory();
       TrainStation trainStation = proxyFactory.getTrainStation();
       trainStation.sell();
   }
}

来源:https://blog.csdn.net/qq_32088869/article/details/129655075

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com