动态代理
模板:
//抽象角色:租房
public interface Rent {
public void rent();
}
//真实角色: 房东,房东要出租房子
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