1、代理

代理就像我们现实生活中的中介。我们一般是找中介买房租的中介找房源的方法,不是直接找房东或者业主,因为中介资源比较多。简而言之,该机构体现了中间商发挥作用的品味。

2、代理模式

代理模式是面向对象编程中常见的设计模式。

3、静态代理

代理类的源代码由程序员创建或工具生成,然后编译代理类。所谓静态是指代理类的字节码文件在程序运行之前就已经存在,代理类和委托类的关系在运行之前就已经确定了。

现在用代码来模拟现实生活中找中介租房的例子。

首先,你要创建一个接口Rent,其中包含一个出租房屋的方法,表示可以出租房屋。

package com.wust.test;
public interface Rent {
    
    void rent();
}

接下来,房东是一个有出租权的角色,一个实际出租房子的角色,需要实现Rent接口。

package com.wust.test;
//包租婆
public class LandLaydy implements Rent{
    
    public void rent() {
    
        System.out.println("包租婆出租房子!!!");
    }
}

接下来,您需要创建一个中介来充当中介来出租房屋。中介不仅可以出租房子,还可以做其他事情,比如收取中介费、签订合同、向人展示房子。

package com.wust.test;
public class Intermediary implements Rent {
    
    private Rent rent;
    public Intermediary(Rent rent){
    
        this.rent = rent;
    }
    public void rent() {
    
        seeHouse();
        
        signContract();
        
        rent.rent();
        
        getFare();
    }
    public void seeHouse(){
    
        System.out.println("带客户看房子!!!");
    }
    public void signContract(){
    
        System.out.println("签租赁合同!!!");
    }
    public void getFare(){
    
        System.out.println("收中介费!!!");
    }
}

最后,创建一个客户端类来模拟找中介租房的过程。

package com.wust.demo;
public class Client {
    
    public static void main(String[] args) {
    
        LandLaydy laydy = new LandLaydy();
        Intermediary intermediary = new Intermediary(laydy);
        intermediary.rent();
    }
}

最终结果。

带客户看房子!!!
签租赁合同!!!
包租婆出租房子!!!
收中介费!!!

4、动态代理

既然是代理,它的功能和用途就和静态代理没什么区别。唯一的区别是动态和静态之间的区别。上一节代码中的Intermediary 类是一个代理。我们需要手动编写代码让 Intermediary 实现 Rent 接口。在动态代理中,我们可以让程序在运行时自动在内存中创建一个实现Rent接口的代理,而不需要定义类Intermediary。这就是为什么它被称为动态的。

另外,动态代理需要用到java反射包中的两个类,Proxy代理类和InvocationHandler类。下面的例子也使用动态代理来模拟代码。

首先还需要创建Rent接口和实现Rent接口的LandLaydy类,然后创建ProxyHandler类来实现InvacationHandler类

package com.wust.demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyHandler implements InvocationHandler {
    
    private Object rent;
    public ProxyHandler(Object rent){
    
        this.rent = rent;
    }
    public Object getProxy(){
    
        return Proxy.newProxyInstance(rent.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
        seeHouse();
        signContract();
        Object res = method.invoke(rent,args);
        getFare();
        return res;
    }
    public void seeHouse(){
    
        System.out.println("带客户看房子!!!");
    }
    public void signContract(){
    
        System.out.println("签租赁合同!!!");
    }
    public void getFare(){
    
        System.out.println("收中介费!!!");
    }
}

最后创建一个Client2类来模拟租赁过程

package com.wust.demo;
import java.lang.reflect.Proxy;
public class Client2 {
    
    public static void main(String[] args) {
    
        LandLaydy laydy = new LandLaydy();
        ProxyHandler handler = new ProxyHandler(laydy);
        //动态生成代理
        Rent rent = (Rent) handler.getProxy();
        rent.rent();
    }
}

结合上面两个例子中介找房源的方法,动态代理和静态代理最直接的区别是:静态代理的代理类需要在程序编译运行前编写好,而动态代理不需要编写具体的代理提前类,只需要创建一个实现InvocationHandler的类,最后通过反射机制在程序执行过程中动态创建代理