动态代理

  1. 模板:
  1. //抽象角色:租房
  2. public interface Rent {
  3. public void rent();
  4. }
//真实角色: 房东,房东要出租房子
package com.study.demo2;

public class Landlord implements Rent {
    public void rent(){
        System.out.println("出租房子!");
    }
}
Object invoke(Object proxy, 方法 method, Object[] args);
//参数
/proxy - 调用该方法的代理实例
//method -所述方法对应于调用代理实例上的接口方法的实例。方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
//args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean.
public class ProxyInvocationHandler implements InvocationHandler {
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
   public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               target.getClass().getInterfaces(),this);

    }

   // proxy : 代理类 method : 代理类的调用处理程序的方法对象.
   // 处理代理实例上的方法调用并返回结果
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       seeHouse();
       //核心:本质利用反射实现!
       Object result = method.invoke(rent, args);
       fare();
       return result;
  }

   //看房
   public void seeHouse(){
       System.out.println("带房客看房");
  }
   //收中介费
   public void fare(){
       System.out.println("收中介费");
  }

}

注意点:target.getClass().getInterfaces(),一类抽象角色

//租客
public class Tenant {
    public static void main(String[] args) {
        Landlord landlord = new Landlord();
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
        proxyInvocationHandler.setTarget(landlord);

        Rent invocation = (Rent) proxyInvocationHandler.getProxy();

        invocation.rent();
    }
}

注意:Rent invocation = (Rent) proxyInvocationHandler.getProxy();类型是接口的,因为可以代理一类抽象角色,如果类型为真实角色会报错
java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to com.study.demo2.Landlord