动态代理有多种我们这里学习接口模式。
我们首先了解java中的两个类Proxy、InvocationHandler接口。
InvocationHandler
public interface InvocationHandlerInvocationHandler是由代理实例的调用处理程序实现的接口 。
每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。
invoke方法
Object invoke(Object proxy,方法 method,Object[] args)throws Throwable
处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。
Proxy
public class Proxy
extends Object
implements SerializableProxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。
这是他下面的几种方法。
static InvocationHandler getInvocationHandler(Object proxy)
返回指定代理实例的调用处理程序。
static 类<?> getProxyClass(ClassLoader loader, 类<?>... interfaces)
给出类加载器和接口数组的代理类的 java.lang.Class对象。
static boolean isProxyClass(类<?> cl)
如果且仅当使用 getProxyClass方法或 newProxyInstance方法将指定的类动态生成为代理类时,则返回true。
static Object newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
测试
创建一个接口、一个实体类。
package aw.Dome1;
public interface Rent {
void as();
}
package aw.Dome1;
public class Host implements Rent{
@Override
public void as() {
System.out.println("正在使用动态代理");
}
}
在创建一个动态代理的类,这个类要添加接口InvocationHandler。
package aw.Dome1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandle implements InvocationHandler {
//被代理的接口
private Rent rent;
public void setRent(Rent rent) {
this.rent = rent;
}
//生成得到的代理类 newProxyInstance这里面的三个参数跟分别是获取当前类加载器、获取接口,当前对象
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;
}
}
测试类
package aw.Dome1;
public class Test1 {
public static void main(String[] args) {
//真实对象
Host host = new Host();
//获取代理对象 先创建代理对象类
ProxyInvocationHandle proxyInvocationHandle = new ProxyInvocationHandle();
//给解库传真实对象
proxyInvocationHandle.setRent(host);
//动态生成代理类
Rent proxy = (Rent) proxyInvocationHandle.getProxy();
proxy.as();
}
}
我们这里也可以把它编程一个万能的。这样你就可以传任意的接口。
package aw.Dome1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandle implements InvocationHandler {
//被代理的解库
private Objecat target;
public void setRent(Objecat 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);
return invoke;
}
}