12.1 动态代理
动态代理的代理类是动态生成的,不是我们直接 去写代理类的代码,然后写好放在那的。
就是我们 专门有一个方法,是来生成 这个代理对象的。都不需要写代理类了。直接根据我们的需求,生成一个代理对象!
- 基于接口的动态代理:JDK 的动态代理。
- 基于类的动态代理:cglib。
- 基于 Java字节码:javassist
需要了解两个类:Proxy、InvocationHandler(调用处理器的接口)
InvocationHandler
: 主要的作用在于 搭配 Proxy.newProxyInstance() 去使用。凡是 实现 这个接口的类,都可以 作为 Proxy.newProxyInstance() 的 第三个参数。为什么要用它呢?因为 我们 代理 附属的 其它 功能和操作,都必须 用 实现 InvocationHandler
接口的 类 来写。也就是说 Proxy.newProxyInstance() 会解析 这个 类。
如果我们要 动态的生成一个 代理对象的话。就必须要 使用 Proxy.newProxyInstance()
这个方法。
那么要使用它,就必须 我们 创建一个类,去实现InvocationHandler
接口。然后 才能往下写。
package top.muquanyu.动态代理;
import top.muquanyu.demo.Rent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
// 被代理的接口,要处理的核心功能。当然 也可以 代表 主角色。
// 因为 无论是 主角色 还是 代理角色 都 实现了 这个接口。
private Rent rent;
public ProxyInvocationHandler(){}
// 被代理的 这个角色 我们要 传递进来。
public ProxyInvocationHandler(Rent rent){
this.rent = rent;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
rent.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(rent, args);
return invoke;
}
}
newProxyInstance
:第一个参数 指的是 一个可以正常 生成一个 代理对象的 构造器。这个构造器 无所谓的。你 写 哪个类的,都行。但是 建议 这个类 是 当前的这个类。第二个参数,被代理对象的反射。第三个参数 是 待解析的 实现 InvocationHandler 的 类。.
我们如果 相加 一些 代理 对象 实现的方法和功能,直接 可以 写到 invoke() 这个 方法里。
写 动态代理的还有一个好处,就是可以 模拟化。就是 大概 都长一个样,你提供 过来什么。我就给你生成 一个 什么样的 代理就行了。
package top.muquanyu.动态代理;
import top.muquanyu.demo.Rent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
// 被代理的接口,要处理的核心功能。当然 也可以 代表 主角色。
// 因为 无论是 主角色 还是 代理角色 都 实现了 这个接口。
private Object target;
public ProxyInvocationHandler(){}
// 被代理的 这个角色 我们要 传递进来。
public ProxyInvocationHandler(Object target){
this.target = target;
}
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
// 主要执行 功能 和方法的 地方。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(target, args);
System.out.println("代理实现的其它功能!");
return invoke;
}
}