动态代理模式

代理模式

代理模式是一种常用的Java设计模式,代理模式是指处理一个业务逻辑时,通过代理的方式完成。代理模式中包含被代理方(委托方)和代理方,委托方委托代理帮助他完成某些工作。在所有的代理模式中,委托方和代理方都有一个共性,即双方都具备完成需求的能力。

Java程序中如何描述这个关系?

        将类所具备的能力封装成接口Java委托类和代理类需要实现同一个接口

代理类和委托类是通过依赖注入进行关联,在设计程序时需要将委托类定义为代理类的成员变量

        1、所有的操作全部在代理类中完成

        2、核心业务操作还是由委托类本身完成

        3、代理类完成其他非核心工作

        4、委托类需要作为成员变量注入到代理类中

代理模式可以分为:静态代理动态代理

        二者区别:静态代理需要提前编写好代理类的代码,在编译期间代理类的class文件就已经生成了,代码是写死的。动态代理是指编译期间代理类的代码不确定,而是在程序运行期间根据代码的指示动态生成的,代码不是写死的,而是灵活变通的。静态代理和反射没有任何关系,动态代理是需要通过反射机制来实现灵活性的。

静态代理

定义一个手机接口类,让其子类实现卖手机功能,手机代理厂商卖不同的手机。

public interface Phone {
    public String salePhone();
}
public class IPhone implements Phone {
    @Override
    public String salePhone() {
        return "卖苹果手机";
    }
}
public class HuaWei implements Phone {
    @Override
    public String salePhone() {
        return "卖华为手机";
    }
}
public class PhoneProxy implements Phone{
    private Phone phone;
    public PhoneProxy(Phone phone) {
        this.phone = phone;
    }
    @Override
    public String salePhone() {
        System.out.println("启动卖手机代理模式");
        return this.phone.salePhone();
    }
}
public static void main(String[] args) {
    PhoneProxy phoneProxy1 = new PhoneProxy(new IPhone());
    System.out.println(phoneProxy1.salePhone());
    PhoneProxy phoneProxy2 = new PhoneProxy(new HuaWei());
    System.out.println(phoneProxy2.salePhone());
}

 此厂商只能代理卖手机的功能,不能代理其他产品,如果需要代理其他产品,则必须修改代码,扩展性差。

动态代理

代码完全不需要修改,可以完成代理机制,只需要写一个辅助类,辅助动态代理机制动态生成真正的代理类。就是动态生成代理类的功能。

Java中如何让一个类具备某种功能?

        Java中用接口定义功能,只需要让目标类实现该接口,目标类就具备了相应的功能。

public class MyInvocationHandler implements InvocationHandler {
    // 记录委托对象
    private Object object;
    
    // 传入委托对象    
    // 返回动态创建的代理对象
    public Object bind(Object o){
        this.object = o;
        // newProxyInstance需要传入3个参数
        // ClassLoader loader, 当前类加载器
        // Class[] interfaces, 实现类的接口
        // InvocationHandler h 当前InvocationHandler实例
        return Proxy.newProxyInstance(MyInvocationHandler.class.getClassLoader(),object.getClass().getInterfaces(),this);
    }

    // invoke通过反射机制来完成方法调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("start proxy...");
        // 委托对象调用核心业务方法
        return method.invoke(object,args);
    }
}

 测试:

Car car = new BMW();
Phone phone = new HuaWei();
MyInvocationHandler invocationHandler = new MyInvocationHandler();
Car bind1 = (Car)invocationHandler.bind(car);
System.out.println(bind1.saleCar());
Phone bind2 = (Phone)invocationHandler.bind(phone);
System.out.println(bind2.salePhone());

动态代理模式_第1张图片

 实现了2种产品的代理。

你可能感兴趣的:(Java,java)