月静好,不过是有人替你负重前行!哪有什么岁

jdk动态代理

什么是动态代理

在程序运行期间,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。

为什么需要动态代理

1.功能增强。当前代码不能满足新需求但又不能改动以前代码时,就可以考虑使用代理,通过代理类,扩展原有类的功能。
2.降低耦合。程序设计时,要遵循一个叫做“单一职责”的原则,该原则要求每个类功能尽可能单一,为什么要单一,因为只有功能单一这个类被改动的可能性才会最小,减少类与类之间的依赖。

DK动态代理的实现

invoke():表示代理对象要执行的功能代码,你的代理类要完成的功能就写在invoke()方法中

(1)代理类要完成的功能

调用目标方法,执行目标方法的功能

增强功能

(2)invoke方法

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

method:目标类中的方法,jdk负责提供method对象

Object[] args:目标类中的参数

Object proxy:jdk创建的代理对象,无需赋值

(3)使用过程

InvocationHandler接口:表示代理要干什么(定义目标类要完成的功能)
创建目标类实现接口
创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能

invoke方法:重写invoke方法,把原来静态代理中代理类要完成的功能写在方法内

method.invoke()是用来执行目标方法的

使用Proxy类的静态方法,来创建代理对象,并把返回值转换为接口类型

核心的对象,创建代理对象,之前的对象都是new类的构造方法,现在我们使用的是Proxy类的方法,代替new的使用

方法newProxyInstance(),作用是创建代理对象,需要三个参数

实现动态代理的步骤:

1.创建接口,定义目标类要完成的功能

public interface UsbSell {
    float sell(float price);
}

2.实现目标类要完成功能的接口

public class UsbFactory implements UsbSell {
    @Override
    public float sell(float price) {
        System.out.println("目标类");
        return 70f;//厂家的U盘价格
    }
}

3.实现InvocationHandler 接口,重写invoke方法。
1.在invoke中调用目标方法。
2.增强功能

//必须实现InvocationHandler接口,完成代理类的功能(调用目标方法、功能增强)
public class MySellHandler implements InvocationHandler {
    private  Object target=null;
    //动态代理的目标对象是活动的,需要传入进来,传进来的是谁就给谁创建代理
    public MySellHandler(Object target){
        this.target=target;
    }
    //args代表传进来的参数(100)
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res=null;
        res=method.invoke(target,args);
        if(res!=null){
            Float price=(Float)res;
            price=price+25;
            res=price;
        }
        System.out.println("淘宝商家返回5元优惠券");
        return res;
    }
}

4.使用Proxy类的静态方法,创建代理对象。并把返回至转为接口类型。

public class Test {
    public static void main(String[] args) {
         //创建目标对象
        UsbSell usbFactory=new UsbFactory();
        //创建invocationHandler对象
        InvocationHandler invocationHandler=new MySellHandler(usbFactory);
        //创建代理对象
        UsbSell proxy= (UsbSell) Proxy.newProxyInstance(
                usbFactory.getClass().getClassLoader(),
                usbFactory.getClass().getInterfaces(),
                invocationHandler
        );
        System.out.println(proxy.sell(100));
    }
}

参考:https://www.cnblogs.com/zhai1997/p/12257150.html

posted @   pz_slider  阅读(202)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
/* 粒子吸附*/
点击右上角即可分享
微信分享提示