设计模式-代理模式之动态代理

目录
基于子类的动态代理
通过一张图直观的看出:
所谓的代理模式,其实就是代理真实对象,达到增强真是对象的目的 。
例如:上图中我在西安,要向联想北京总公司(真实对象)买电脑,西安有一个北京联想公司的代理商,显然跑去北京买太不划算了,所以可以直接向代理商买,代理商从中赚差价 。总公司和代理商直接存在着一些关联,例如代理商需要从总公司进货,代理商的价格不能太高等…
静态代理:有一个类文件描述代理模式动态代理:在内存中形成代理类 特点:字节码随用随创建,随用随加载作用:不修改源码的基础上,对方法进行增强

设计模式-代理模式之动态代理

文章插图
动态代理示例:
联想总公司
public interface SaleComputer {public String sale(double money);public void show();}
西安联想代理商
public class Lenvov implements SaleComputer {public String sale(double money) {System.out.println("花了"+money+"钱买电脑");return "联想电脑...";}public void show() {System.out.println("展示电脑...");}}
方法执行
public class ProxyTest {public static void main(String[] args) {//1.创建真实对象final Lenvov lenvov = new Lenvov();//动态增强lenvov对象:/*** 参数:*1.代理对象类加载器:lenvov.getClass().getClassLoader()* 用于加载代理对象字节码文件,和被代理对象使用相同的类加载器*2.接口数组:保证了真实对象和代理对象实现相同的接口:lenvov.getClass().getInterfaces()*3.** 可以强制转为SaleComputer是因为:代理对象和正式对象实现了相同的接口*/SaleComputer proxy_sc = (SaleComputer) Proxy.newProxyInstance(lenvov.getClass().getClassLoader(),lenvov.getClass().getInterfaces(),new InvocationHandler() {/*** 代理逻辑编写的方法:每一次代理对象调用方法,都会执行这个函数* @param proxy: 代理对象=proxy_sc* @param method :代理对象调用的方法,会被封装成Method对象* @param args :代理对象调用的方法实际传递的参数* @return :代理对象调用方法时的返回值* @throws Throwable*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("invoke...被执行了");if (method.getName().equals("sale")){System.out.println("代理商专车接送过来买电脑...");//1.增强参数double money = (Double)args[0];money *=0.85;//2.增强方法执行的方法体String invoke = method.invoke(lenvov, money);//返回电脑System.out.println("代理商专车接送回去...");//3.增强返回值return invoke+"鼠标垫"; //返回代理对执行的结果}else {Object invoke = method.invoke(lenvov, args);return null;}}});//3.调用方法String sale = proxy_sc.sale(7000);System.out.println(sale);//proxy_sc.show();}}
内部逻辑就是用户给出7000块去买代理商电脑,代理商对收到的7000元进行85折,自己回收15%,85%付给了联想公司,所以这边输出:花了5950买电脑是其实是代理商向联系公司买电脑花的钱,而不是用户向联想公司花的钱,被赚差价了 。
函数返回值是代理对象的执行结果 。
不基于子类的动态代理 被代理类
public class Lenvov {public String sale(double money) {System.out.println("花了"+money+"钱买电脑");return "联想电脑...";}public void show() {System.out.println("展示电脑...");}}
测试方法:
【设计模式-代理模式之动态代理】/*** 不基于子类的动态代理**/public class ProxyTest {public static void main(String[] args) {//1.创建真实对象final Lenvov lenvov = new Lenvov();//动态增强lenvov对象:Lenvov proxy_lenvov = (Lenvov)Enhancer.create(lenvov.getClass(),new MethodInterceptor() {/*** 执行被代理对象的任何方法都会经过该方法* 可以强制转为SaleComputer是因为:代理对象和正式对象实现了相同的接口* @param proxy :代理对象* @param method:代理对象执行的方法,会被封装成Method方法* @param args :代理对象调用的方法实际传递的参数* @param methodProxy:当前执行对象的代理方法* @return :代理对象调用方法时的返回值* @throws Throwable*/public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("invoke...被执行了");if (method.getName().equals("sale")){System.out.println("代理商专车接送过来买电脑...");//1.增强参数double money = (Double)args[0];money *=0.85;//2.增强方法执行的方法体Object invoke = method.invoke(lenvov, money);//返回电脑System.out.println("代理商专车接送回去...");//3.增强返回值return invoke+"鼠标垫"; //返回代理对执行的结果}else {Object invoke = method.invoke(lenvov, args);return null;}}});String sale = proxy_lenvov.sale(10000);System.out.println(sale);}}