动态代理
- 动态代理的角色与静态代理的一样
- 动态代理的代理类是自动生成的,静态代理的代理类是我们自己提前手写的
- 动态代理分为两类:一种基于接口,一种基于类
- 基于接口—>JDK动态代理
- 基于类 —> cglib
- 现在用的比较多的是 javasist 来生成动态代理 .
- 但是道理都是一样的
JDK动态代理需要了解两个类:
核心 : InvocationHandler 和 Proxy
打开JDK API
java.lang.reflect 包下的 InvocationHandler 接口
【InvocationHandler:调用处理程序】
Object invoke(Object proxy, Method method, Object[] args)
参数:
proxy —> 调用该方法的代理实例
method —> 所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
args —> 包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。
【Proxy : 代理】
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler ih) throws IllegalArgumentException
参数:
loader —> 类加载器来定义代理类
interfaces —> 代理类实现的接口列表
ih —> 调度方法调用的调用处理函数
代码实现
抽象角色和真实角色和之前的一样!
//抽象角色:租房
public interface Renting {
void rent();
}
//真实角色: 房东,房东要出租房子
public class Landlord implements Renting{
public void rent() {
System.out.println("出租房子");
}
}
现在我们新增一个类ProxyInvocationHandler实现**InvocationHandler**用来自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
/**
newProxyInstance(ClassLoader loader,
类<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
*/
//创建动态代理类和实例
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
// proxy : 代理类
// method : 代理类的调用处理程序的方法对象
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(target,args);
return result;
}
}
现在我们客户来租房:
public class Client {
public static void main(String[] args) {
//真实对象(这个是不变的)
Landlord ld = new Landlord();
//代理对象的调用处理程序
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setTarget(ld); //设置要代理的对象
Renting rt = (Renting) pih.getProxy(); //动态生成代理类!
rt.rent();
}
}
可以看到,这样我们完全可以不用手写代理类,代码量大大减少。弥补了静态代理的缺点
动态代理的好处
1.可以使我们的真实角色更加纯粹,不再去关注一些公共的事情。
2.公共的业务由代理去完成,实现了**业务分工**
3.公共业务发生拓展是更加集中和方便。
4.一个动态代理,一般代理某一个业务
5.一个动态代理可以**代理多个类**,代理的是接口