关于代理模式粗略理解

代理模式

简单来说就是代理对象起到中介的作用

流程也就是:使用者 - 代理 - 服务者

用图表示则为:
在这里插入图片描述

好处

可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.

因为别人写的代码是可以正常运行的,如果随便修改源代码出现bug了就难顶了~

因此如果需要修改,可以通过代理的方式来扩展该方法

静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.

例子

我们定义一个接口

public interface Store {
    void sale();
}

然后定义一个实现类

public class StoreImpl implements Store{
    @Override
    public void sale() {
        System.out.println("卖东西");
    }
}

然后定义代理

public class StoreProxy implements Store {
    private Store targetObj;

    public StoreProxy(Store targetObj) {
        this.targetObj = targetObj;
    }

    @Override
    public void sale() {
        System.out.println("前驱代码");
        targetObj.sale();
        System.out.println("后继代码");
    }
}

测试

public class Test {
    public static void main(String[] args) {
        Store store = new StoreImpl();
        StoreProxy proxy = new StoreProxy(store);
        proxy.sale();
    }
}

执行结果

前驱代码
卖东西
后继代码
综上所述

一、好处:
可以做到在不修改目标对象的功能前提下,对目标功能扩展.

二、缺点:

①因为代理类需要与实现类实现一样的接口,所以会有很多代理类

②一旦接口增加方法,目标对象与代理对象都需要修改

为了解决这些缺点 我们引入动态代理

动态代理

动态代理有以下特点:
①.不需要实现接口
②.代理对象的生成是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
③因此动态代理也叫做:JDK代理,接口代理

使用的API

java.lang.reflect.Proxy类的

/**
 *
 * @param loader 指定当前目标对象使用类加载器
 * @param interfaces :目标对象实现的接口的类型
 * @param h 事件处理,执行目标对象的方法时,会触发事件处理器的方法,
 * 会把当前执行目标对象的方法作为参数传入。简单来说就是=>如何代理
 * @return
 */
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h){

}
例子

接口和实现类跟静态代理是一样的,就不重复写了.

首先是一个创建代理对象的工厂

package ProxyDemo.DynamicProxyDemo;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {
    private StoreImpl targetObj;

    public ProxyFactory(StoreImpl targetObj) {
        this.targetObj = targetObj;
    }

    public Object createProxyInstance(){
        return  Proxy.newProxyInstance(targetObj.getClass().getClassLoader()
                , targetObj.getClass().getInterfaces(),
                (Object proxy, Method method, Object[] args) -> {
                    System.out.println("前驱代码");
                    //这里args写不写都行 因为是args里啥都没有
                    Object obj = method.invoke(targetObj,args);
                    System.out.println("后继代码");
                    return obj;
                });
    }
}

然后是测试

public class Test {
    public static void main(String[] args) {
        StoreImpl obj = new StoreImpl();
        Store proxy = (Store) new ProxyFactory(obj).createProxyInstance();
        proxy.sale();
    }
}

执行结果

前驱代码
卖东西
后继代码

总结

动态代理不需要实现接口,但是目标(实现类)对象通常要实现接口,否则不能用动态代理。

目标对象的方法就是让代理对象调用invoke来执行的

当然我们也可以不写实现类,那么在说明如何代理的时候
也就是传递InvocationHandler h这个参数的时候 说明如何代理即可。换句话说就是把invoke的内容移动到这了而已。

至于不写实现类的例子…咕咕咕,有缘再更

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值