动态代理

Java动态代理

代理模式:代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。

这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

一、静态代理

被代理的接口

public interface UsbProducer {
    float sell(int num);
}

目标类

/**
 * 目标类:实现了生产Usb的接口
 */
public class KingUsbFactory implements UsbProducer{
    @Override
    public float sell(int num) {
        int price = 88;
        System.out.println("目标类执行了方法---");
        return num*price;
    }
}

代理类

/**
 * TaoBao是KingUserFactory的代理类
 */
public class TaoBao implements UsbProducer{

    KingUsbFactory kingUsbFactory;

    //通过构造方法传入目标对象
    public TaoBao(KingUsbFactory kingUsbFactory) {
        this.kingUsbFactory = kingUsbFactory;
    }

    @Override
    public float sell(int num) {

        //调用目标类
        float price = kingUsbFactory.sell(num);

        //功能增强
        price += 25*num;
        System.out.println("代理类执行了方法---");

        return price;
    }
}

测试静态代理结果

 public static void main(String[] args) {
        //静态代理
        TaoBao taoBao = new TaoBao(new KingUsbFactory());
        System.out.println(taoBao.sell(2));
     
目标类执行了方法---
代理类执行了方法---
226.0     

静态代理特点:

1.实现简单,易于理解。

2.目标类是固定的,要代理另一个目标类,必须重新写一个代理类,十分麻烦。

二、动态代理

1.JDK动态代理:通过Java的反射技术,在程序运行时生成一个目标接口的代理类实例对象,从而实现对目标类的调用和功能增强。

1)实现InvocationHandler接口

/**
 * InvocationHandler类实现的invoke()内容,是代理类实现的业务逻辑:目标类方法+代理类的增强
 */
public class MyHandler implements InvocationHandler {

    //目标类
    Object target;

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

    /*invoke(proxy,method,args)
    proxy:代理对象,newProxyInstance方法的返回对象

	method:调用的方法

	args: 方法中的参数*/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("执行目标类之前的增强++++++++++++++++++");

        //调用目标类方法
        float price = (float) method.invoke(target, args);


        //实现功能增强
        System.out.println("动态代理的功能增强++++++++++++++++++++++");
        float n= price;
        int x = (Integer) args[0];
        price += x*25;


        return price;
    }
}

2)通过Proxy创建一个代理对象

//动态代理
        //目标类
        UsbProducer usbProducer = new KingUsbFactory();

        InvocationHandler invocationHandler = new MyHandler(usbProducer);

        //Proxy.newProxyInstance(a1,a2,a3)
        //a1:要代理的接口的类加载器
        //a2:目标类的接口
        //a3:实现的invocationHandler
        UsbProducer usbProducerAfter = (UsbProducer) Proxy.newProxyInstance(UsbProducer.class.getClassLoader(),
                                usbProducer.getClass().getInterfaces(),
                                invocationHandler);

        float price = usbProducerAfter.sell(2);
        System.out.println("最终价格为:"+price);

执行目标类之前的增强++++++++++++++++++
目标类执行了方法---
动态代理的功能增强++++++++++++++++++++++
最终价格为:226.0

JDK动态代理特点:

1)目标对象并不固定,而是活动的,可以由程序员传入。

2)程序员不需要手动编写代理类,而是通过java的反射技术动态生成,省去了很多麻烦。

3)通过Proxy生成的代理对象调用代理方法时,实际上是调用了InvocationHandler中的invoke()。

4)JDK动态代理要实现有一个前提:目标类必须实现了接口,因此,要对普通目标类进行动态代理,要用到CGLib。


2.CGLib动态代理

原理:java的继承机制。代理类继承目标类,并重写目标方法,当创建代理类对象并声明为目标类类型时,调用方法实现的是代理类的方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值