动态代理类的实现
动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的。
动态代理分为两大类:基于接口的动态代理,基于类的动态代理。
- 基于接口-----JDK动态代理,
- 基于类—cglib
- java字节码实现:javasist
需要了解两个类,
Proxy,提供创建动态代理类和实例的静态方法。
InvocationHandler,调用处理程序实现接口。
动态代理的好处
1.可以真实的角色的操作更加的纯粹,不用去关注一些公共的业务。
2.公共交给代理角色,实现了业务的分工
3.公共的业务发生扩展的时候,方便集中管理
4.一个动态代理类代理的是一个接口,一般就是对应的一类业务
5.一个动态代理类可以代理多个类,只要是实现了同一个接口。
案例:
//真实角色
public class Host implements Rent{
public void rent() {
System.out.println("我是房东,我要出租房子");
}
}
//接口
public interface Rent {
public void 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 void setRent(Rent rent) {
this.rent = rent;
}
/*
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。
* 通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,
* 并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。
* 调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。
*
* */
//生成得到代理类
public Object getProxy(){
//生成的代理类有三个参数,第一个是通过反射获取相应的代理实例,第二个是通过反射获取代理实现的接口,第三个是处理方法就是它本身
//我们所讲的classLoader,就是负责把磁盘上的.class文件加载到JVM内存中,类加载器getClassLoader()
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
//处理代理实例并返回结果。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是使用反射机制实现
seeHouse();//当新增代理类的方法时,直接在此处加入即可,就把代理的对象方法传入新的代理
Object result= method.invoke(rent, args);
return result;
}
public void seeHouse(){
System.out.println("中介带你看房");
}
}
//测试类
public class Client {
public static void main(String[] args) {
//真实角色
Host host=new Host();
//代理角色
ProxyInvocationHandler handler = new ProxyInvocationHandler();
//通过调用程序处理角色来处理我们要调用的接口对象
handler.setRent(host);//传递代理角色
//这里的proxy就是动态生成的,我们并没有写
Rent proxy = (Rent) handler.getProxy();//获取代理生成代理类
proxy.rent();//由代理类来租房
}
}