抽象角色:一般使用接口或者抽象类来实现
真实角色:被代理的角色
代理角色:代理真实角色;代理真实角色后,一般会做一些附属的操作
客户:使用代理角色来进行一些操作
接口
/** * 抽象角色 */ public interface Rent { public void rent(); }实体
/** *真实角色:房东 **/ public class Host implements Rent { public void rent() { System.out.println("房屋出租"); } } /** *代理对象:Proxy **/ public class Proxy implements Rent { private Host host; public Proxy(){ } /** *设置一个代理对象 * @param host(传入要出租房的人) * @return */ public Proxy(Host host){ this.host = host; } /** * 代理内容 */ public void rent(){ seeHouse(); host.rent(); fare(); } /** * 中介添加的内容(看房) */ public void seeHouse(){ System.out.println("带房客看房"); } /** * 中介添加的内容(收中介费用) */ public void fare(){ System.out.println("收取中介费"); } } /** *真实角色:客户 **/ public class client { public static void main(String[] args) { //获取房东对象 Host host = new Host(); //给代理对象传入房东.目的确定信息 Proxy proxy = new Proxy(host); //通过中介租房 proxy.rent(); } }备注
重点理解让真实角色专注于自己业务的实现,其他业务交给代理角色
动态代理的角色和静态代理的一样 .
动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
基于接口的动态代理----JDK动态代理基于类的动态代理–cglib现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist我们这里使用JDK的原生代码来实现,其余的道理都是一样的!、JDK的动态代理需要了解两个类
核心
InvocationHandler 和 Proxy , 打开JDK帮助文档看看
InvocationHandler:调用处理程序
接口
/** * 抽象角色 */ public interface Rent { public void rent(); }实体
/** * 真实角色:房东,房东要出租房子 */ public class Host implements Rent { public void rent() { System.out.println("房屋出租"); } } /** *代理角色 **/ public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口对象 private Rent rent; public void setRent(Rent rent){ this.rent = rent; } /* Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。 Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class<?>[] { Foo.class }, handler); 参数:this.getClass().getClassLoader() 代理类的类加载器, rent.getClass().getInterfaces() 被代理类的接口, this 代理类的实例 */ public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /*核心:本质利用反射实现 *method.invoke(rent,args);利用反射调用类里面的实际方法 *Object result 方法的返回值,如果没有,返回为null */ Object result = method.invoke(rent,args); return result; } /** * 看房 */ public void seeHouse(){ System.out.println("带房客看房"); } /** * 收中介费 */ public void fare(){ System.out.println("收中介费"); } } public class Client { public static void main(String[] args) { //真实角色 Host host = new Host(); //代理实例的调用处理程序 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //将真实角色放置进去! pih.setRent(host); //动态生成对应的代理类! Rent proxy = (Rent)pih.getProxy(); proxy.rent(); } }重点理解:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口!、
初浅理解:
动态实际上就是实现InvocationHandler接口,一切交给程序处理
初步需要理解(这些就足够了):
/*参数:this.getClass().getClassLoader() 代理类的类加载器, rent.getClass().getInterfaces() 代理类的类加载器, this 代理类的实例 */ public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /*核心:本质利用反射实现 *method.invoke(rent,args);利用反射调用类里面的实际方法 *Object result 方法的返回值,如果没有,返回为null */ Object result = method.invoke(rent,args); return result; }通用的动态代理实现的类
所有的代理对象设置为Object即可
public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target){ this.target = target; } /* Proxy提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。 Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class<?>[] { Foo.class }, handler); */ public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //核心:本质利用反射实现 Object result = method.invoke(target,args); return result; } }动态代理相比静态减少了代码量,静态代理要一个类就就要配置一个代理类,而动态代理则可以代理多个类