jdk动态代理和cglib动态代理实现及区别

        代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

代理模式又分为:静态代理、jdk动态代理、cglib动态代理。由于静态代理会产生过多的代理类,一旦接口增加方法,目标对象与代理对象都要进行修改,不易维护。而动态代理是动态地在内存中构建代理对象,从而实现对目标对象的代理功能,接口增加方法时代理对象不受影响 。下面我们讲讲jdk动态代理和cglib动态代理实现及区别

jdk动态代理实现

@Test
public void test(){
    //目标对象
        Person target = new Intermediary("中介1号", new Tenant("李四"));
        //InvocationHandler
        InvocationHandler handler = new RentInvocationHandler(target);
        //获取代理对象
        Person proxyInstance = (Person) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
        //通过代理对象调用
        proxyInstance.rentHouse();
}
 
// 代理对象
public class RentInvocationHandler implements InvocationHandler {

    /**
     * 被代理的目标对象
     */
    private Object target;

    public RentInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("租房前预处理工作...");
        Object returnValue = method.invoke(target, args);
        System.out.println("租房后善后工作...");
        return returnValue;
    }
}

 
// 目标对象接口
public interface Person {

    /**
     * 租房
     */
    void rentHouse();
}

public class Intermediary implements Person {

    private String name;

    /**
     * 租房者
     */
    private Person tenant;

    public Intermediary(String name, Person tenant) {
        this.name = name;
        this.tenant = tenant;
    }

    @Override
    public void rentHouse() {
        System.out.println("中介 " + this.name + "确定租房预算,带领查看房源...");
        tenant.rentHouse();
        System.out.println("中介 " + this.name + "带领客户租房完成,合同签订完成,收取佣金,准备跑路...");
    }
}


public class Tenant implements Person {

    private String name;

    public Tenant(String name) {
        this.name = name;
    }

    @Override
    public void rentHouse() {
        System.out.println(this.name + " 正在租房中...");
    }
}

cglib动态代理

@Test
public void test(){
    //目标对象
        Runner runner = new Runner("李四");
        //代理对象
        RunnerMethodInterceptor interceptor = new RunnerMethodInterceptor(runner);
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(runner.getClass());
        //设置回调
        enhancer.setCallback(interceptor);
        Runner proxyInstance = (Runner) enhancer.create();
        proxyInstance.run();
}
 
// 代理对象
public class RunnerMethodInterceptor implements MethodInterceptor {

    /**
     * 目标对象
     */
    private Object target;

    public RunnerMethodInterceptor(Object target) {
        this.target = target;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("踢两脚 加速...");
        Object returnVal = method.invoke(target, objects);
        System.out.println("拽两下 减速...");
        return returnVal;
    }
}

public class Runner {

    private String name;

    public Runner() {
    }

    public Runner(String name) {
        this.name = name;
    }

    public void run() {
        System.out.println(this.name + " 跑的飞快...");
    }
}

区别 


1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。
2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。
3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值