粗谈Java中的代理模式

代理模式

为其他对象提供一个代理以控制对某个对象的访问,其实就是代理类替被代理类实现业务,对被代理类的一种加强,代理分两种:静态代理和动态代理

以现实中的明星和代理人为例子吧

静态代理

接口:就是代理类和被代理的共同行为,明星唱跳是基本了

public interface Star{
    void sing();
}

被代理类:不面向外部,业务都由代理类承接,以明星夏洛为例

public class Xialuo implements Star{
    @Override
    public void sing() {
        System.out.println("雪花飘飘,北风萧萧,天地一片苍茫");
    }
}

代理类:面向外部,首先你得跟经纪人马冬梅预约夏洛,他才会出席给你唱歌

public class Madongmei implements Star{

    private Xialuo xialuo = new Xialuo();
    
    @Override
    public void sing() {
        System.out.println("让我们欢迎夏洛来一首一剪梅" );
        xialuo .sing();
    }
}

代理类调用:
被代理类被传递给了代理类Madongmei ,代理类在执行具体方法时通过所持用的被代理类完成调用。

    public static void main(String[] args) {
        Madongmei madongmei = new Madongmei ();
        madongmei .sing();
    }
    
输出:
让我们欢迎夏洛来一首一剪梅
雪花飘飘,北风萧萧,天地一片苍茫

使用静态代理很容易就完成了对一个类的代理操作。 但是静态代理的缺点也暴露了出来:由于代理只能为一个类服务,如果需要代理的类很多,那么就需要编写大量的代理类,比较繁琐, 毕竟马冬梅这个经纪人名下也不是只有夏洛一个明星--------动态代理就来了

动态代理

如何理解静态和动态?

静态:代理类是创建了的,比如例子中的刘小爱
动态:代理类是不用创建的
在Java里有一个类叫Proxy,翻译过来就是代理的意思。
用这个类可以动态构建一个代理类对象,它有一个静态方法newProxyInstance(),用类名直接可以调用,我们来看看这个方法的参数

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

①ClassLoader loader

类加载器,就是被代理类的类加载器

②Class<?>[] interfaces

interfaces,接口的意思,这个参数就是接口对应的Class对象,什么接口?就是被代理类实现的接口,因为它可以实现很多个接口,所以是一个数组。

③InvocationHandler h
InvocationHandle,翻译过来就是调用处理器,再看看这个接口,其实也就是例子中Madongmei这个类对star接口中的三个抽象方法的重写。

具体的业务逻辑,根据不同的需求编写不同的代码,其它的代码都是基本不变的。

public interface InvocationHandler extends Callback {
    Object invoke(Object var1, Method var2, Object[] var3) throws Throwable;
}

该接口只有一个方法invoke:

proxy:这个就是代理对象
method:这个也就是代理对象调用的方法(例子中的sing方法)
args:这个是方法中的参数
好,以上就是对newProxyInstance()方法的说明,完全弄懂了这个方法,也就弄懂了动态代理。

接口、被代理类不变,我们构建一个handler类来实现InvocationHandler接口,这是方便代理对象构建InvocationHandler的。

public class ProxyHandler implements InvocationHandler{
    private Object object;
    public ProxyHandler(Object object){
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName());
        method.invoke(object, args);
        return null;
    }
}

执行动态代理:

public static void main(String[] args) {

    Xialuo xiaLuo= new Xialuo ();-------先创建被代理类的的加载器、接口
    ClassLoader classLoader = xiaLuo.getClass().getClassLoader()
    Class<?>[] interfaces = xiaLuo.getClass().getInterfaces();

    InvocationHandler handler = new ProxyHandler(xiaLuo);
    Star proxy= (Star) Proxy.newProxyInstance(classLoader , interfaces  , handler);
    -------代理类Madongmei我们是没有创建的,所以用的是它的父接口star来接受代理类对象,这是多态。----------

    proxy.sing();
}

输出:
让我们欢迎夏洛来一首一剪梅
雪花飘飘,北风萧萧,天地一片苍茫
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值