您好,欢迎来到华佗小知识。
搜索
您的当前位置:首页jdk动态代理和cglb动态代理

jdk动态代理和cglb动态代理

来源:华佗小知识


概述

动态代理和静态代理都是代理模式的实现方式,其主要区别在于代理类生成的时机和方式。

静态代理是在编译时就确定了代理类的代码,在程序运行前就已经存在了代理类的class文件。代理类与委托类的关系在编译时就已经确定,因此被称为静态代理。在静态代理中,代理类需要实现与委托类相同的接口或者继承委托类的父类,以便能够对委托类进行代理操作。

动态代理是在程序运行时生成代理类的代码,代理类通过反射机制动态生成。动态代理不需要像静态代理一样实现与委托类相同的接口或继承委托类的父类,它可以实现任意接口。动态代理的优势在于,在代理类和委托类之间增加一个代理对象,可以更加灵活地控制委托类的行为。同时,也可以使得代码更加通用化,减少代码的重复性。

总体来说,静态代理只能代理一个委托类,而动态代理可以代理多个委托类。但是,由于动态代理的实现机制比较复杂,所以相比静态代理,动态代理的性能开销更大。而静态代理虽然只能代理一个委托类,但是因为它是在编译时生成代码,所以相对来说执行效率更高。

在程序运行阶段,在内存中动态生成代理类,被称为动态代理,目的是为了减少代理类的数量。解决代码复用的问题。

DK动态代理技术:只能代理接口。

CGLIB动态代理技术:CGLIB(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。它既可以代理接口,又可以代理类底层是通过继承的方式实现的。性能比JDK动态代理要好。(底层有一个小而快的字节码处理框架ASM。)

JDK动态代理

一个接口和一个实现类

接口类==>jdk动态代理必须要有一个接口类

invoke 方法,用户调用代理对象的什么方法,实质上都是在调用处理器的
invoke 方法,通过该方法调用目标方法,它也有三个参数:

public Object invoke(Object proxy, Method method, Object[] args)

orderService

public interface orderService {
    public void order();
}

orderServiceImp

public class orderServiceImp implements  orderService{
    @Override
    public void order() {
        System.out.println("order....");
    }
}

proxyOrderService 

public class proxyOrderService {
    public static void main(String[] args) {
        orderServiceImp orderServiceImp = new orderServiceImp();
        orderService o = (orderService)Proxy.newProxyInstance(orderServiceImp.class.getClassLoader(),
                orderServiceImp.class.getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        orderServiceImp.order();
                        return null;
                    }
                }
        );
        o.order();
    }
}

 代码可以封装为以下:

public class proxy implements InvocationHandler {

    private  orderService orderService;

    public proxy(orderService orderService) {
        this.orderService = orderService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy");
        method.invoke(orderService,args);
        return null;
    }
}
public class proxyOrderService {
    public static void main(String[] args) {
        orderServiceImp orderServiceImp = new orderServiceImp();
        orderService o = (orderService)Proxy.newProxyInstance(orderServiceImp.class.getClassLoader(),
                orderServiceImp.class.getInterfaces(), new proxy(orderServiceImp)
        );
        o.order();
    }
}

 cglb动态代理

CGLIB既可以代理接口,又可以代理类。底层采用继承的方式实现。所以被代理的目标类不能使用final修饰。

和JDK动态代理原理差不多,在CGLIB中需要提供的不是InvocationHandler,而是:net.sf.cglib.proxy.MethodInterceptor 

使用CGLIB,需要引入它的依赖:

<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>3.3.0</version>
</dependency>

准备一个接口(cglb可以不用接口哈),一个类

public interface orderService {
    public void order();
}
public class orderServiceImp implements orderService {
    @Override
    public void order() {
        System.out.println("order....");
    }
}
public class test {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        orderServiceImp orderServiceImp = new orderServiceImp();
        enhancer.setSuperclass(orderServiceImp.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object target, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object invoke = method.invoke(target, objects);
                return invoke;
            }
        });
        orderServiceImp o =(orderServiceImp)enhancer.create();
        orderServiceImp.order();
    }
}

MethodInterceptor接口中有一个方法intercept(),该方法有4个参数:

第一个参数:代理对象

第二个参数:目标方法

第三个参数:目标方法调用时的实参

第四个参数:代理方法

 对于高版本的JDK,如果使用CGLIB,需要在启动项中添加两个启动参数:

  • --add-opens java.base/java.lang=ALL-UNNAMED
  • --add-opens java.base/sun.net.util=ALL-UNNAMED

CGLIB使用步骤:

1、创建字节码增强器

2、设置目标对象

3、设置回调函数

4、创建代理对象

5、使用代理对象

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务