静态代理与动态代理

代理是一种设计模式,以租房子为例,以前房东都是直接联系租客,带租客看房子租房子等等,后来房东觉得这一系列的流程太麻烦了,就诞生了中介这一职位,这里的中介其实就是“代理”。房东只想要出租房子,不想涉及其他事情,中介代理房东出租房子,换句话说就是:房东只需要关注自己的业务逻辑就可以了。这就是代理模式在生活中直观的体现。

静态代理

先上代码

定义抽象层,我理解为行为标准,这里就是出租房子服务

public interface RentService {
    void rentHouse();
}
复制代码

定义真实角色,这里即为房东,实现上面接口

public class Landlord implements RentService {
    
    @Override
    public void rentHouse() {
        System.out.println("房东出租房子");
    }
}
复制代码

定义代理角色,这里就是中介

public class Proxy implements RentService{
​
    private Landlord landlord;
​
    public Proxy(Landlord landlord){
        this.landlord = landlord;
    }
​
    @Override
    public void rentHouse() {
        //System.out.println("中介带看房");
        landlord.rentHouse();
        //System.out.println("签合同");
    }
}
复制代码

应用程序

public static void main(String[] args) {
        Proxy proxy = new Proxy(new Landlord());
        proxy.rentHouse();
    }
复制代码

运行 打印:房东出租房子

在应用程序里,房东啥也没做,我们就创建一个代理,并代理房东。表面上是中介在出租房子,其实是房东在出租房子,并且代理可以做些增强处理,比如带租客看房子签合同等等。

静态代理优点:业务只需关注业务本身

缺点:1.如果新增一个真实对象,就要新增一个代理类

2.如果抽象接口里新增了一个方法,那么真实角色和代理都要去实现它,增加了代码的复杂度,维护成本较高

动态代理

动态代理是通过反射来实现的,老规矩,先上代码

动态代理

public class DynamicProxy implements InvocationHandler {
​
    private Object proxyObject;
​
    public Object newInstance(Object proxyObject) {
        this.proxyObject = proxyObject;
​
        return Proxy.newProxyInstance(proxyObject.getClass().getClassLoader(),
                proxyObject.getClass().getInterfaces(),this);
    }
​
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = method.invoke(proxyObject, args);
        return result;
    }
}
复制代码

程序

    public static void main(String[] args) {
        DynamicProxy proxy = new DynamicProxy();
        RentService service = (RentService) proxy.newInstance(new Landlord());
        System.out.println(service.getClass());
        service.rentHouse();
    }
复制代码

打印:class com.sun.proxy.$Proxy0 房东出租房子

可见RentService service = (RentService) proxy.newInstance(new Landlord())拿到的是代理对象,代理对象通过invoke方法调了对应的方法。动态代理解决了静态代理带来的弊端。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享