代理模式—基于JDK(接口)的动态代理的使用方法

代理模式—基于JDK(接口)的动态代理的使用方法

什么是代理模式?

代理模式就是给对象提供一种代理对象去控制对该对象的访问,代理类与委托类有同样的接口,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

相当显示生活中的:外卖、房产中介

优点:代理模式在访问实际对象时引入一定程度的间接性,可以做到在不修改对象代码的基础上对原对象 的功能进行修改或增强(低耦合性,高扩展性)

Java中的代理模式

  • 目标类:原对象,我们需要通过代理对象控制它的访问,扩展其功能

  • 代理类:代理模式产生的对象,是原对象的“替身"

静态代理

概念

就是手动写死的代理类代码,在编译时就已经将目标类和代理类确定下来

实例

以点外卖为例,顾客为目标类

public class  Customer {
    public string order(String foodName){
        return"下单"+foodName;
    }
}

创建代理类外卖小哥

public class DeliveryClerk extends Customer{
    @Override
    public string order(String foodName) {
        String result = super.order(foodName);
        system.out.print1n("骑士正前往取餐...");
        return result+"正在派送";
    }
}
​

顾客点外卖

public class staticDemoTest {
    public static void main(String[ ] args) {
        //创建一个顾客对象
        customer customer = new DeliveryClerk();
        string result = customer.order("老八秘制小汉堡");
        system.out.print1n(result);
    }
}

缺点

维护依然复杂,父类或接口一发生变动,代理类就要修改。若代理类较多维护将十分困难。所以实际开发时常用动态代理

动态代理

概念

动态代理技术,是在内存中生成代理对象的一种技术。整个代理过程在内存中进行,我们不需要手写代理类的代码,而是直接在运行期,在JVM中凭空造出一个代理类对象供我们使用。

基于JDK(接口)的动态代理的使用方法

JDK有自带动态代技术,需要使用一个静态方法创建代理对象,要求相应的目标类必须实现接口

点单接口

public interface OrderInterface {
    public String order(String foodName) ;
    public void test();
    public void test2();
}

目标类

public class Customer implements OrderInterface{
    @override
    public String order(String foodName){
        ...
        return"已下单"+foodName;
    }
    
    @override
    public void test(){}
    
    @override
    public void test2(){}
}

测试类

实现*InvocationHandler接口*是最关键的地方,InvocationHandler中有一个invoke方法,所有执行代理对象的方法都会被替换成执行invoke方法。

public class DynamicTest {
    public static void main(String[] args) {
        //顾客对象
        Customer customer =new customer();
        //使用JDK的API工具,动态生成代理对象
        orderInterface deliveryClerk =(OrderInterface) Proxy.newProxyInstance(
            customer.getClass().getclassLoader(),
            customer-getC1ass().getInterfaces(),
            new InvocationHandler() {
                 @Override
                public Object invoke(object proxy,Method method,object[] args)
                    throws Throwable {
                        if ( "order".equals(method.getName())) {
                            Object result = method.invoke( customer,args );
                            ...
                            return result + "送达";
                        }else{
                            return method.invoke(customer, args);//使用method反射调用,
                            //原封不动调用原来的逻辑
                        }
                }
            }
        );
        //调用代理对象,执行对应方法
         String result = deliveryclerk.order( foodName:"老八秘制小汉堡");
         System.out.println(result);
          deliveryClerk.test();
    }
}

实际上,order并没有执行,执行的是InvocationHandler中的invoke方法

所有被代理执行的方法,都是通过在InvocationHandler中的invoke方法调用的,所以我们只要在invoke方法中统一处理,就可以对所有被代理的方法进行相同的操作了

Object invoke(Object proxy,Method method,Object[] args)
  • proxy:就是代理类对象的一个引用

  • method:对应的是出发invoke执行的方法的Method对象。假如我们调用了xxx方法,该方法触发了invoke的执行,那么,method就是xxx方法对应的反射对象(Method对象)

  • args:调用方法时传递的实际参数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值