这样和妻子解释:Java动态代理机制详解(JDK和CGLIB( 三 )
package com.foo.proxy;/*** 售票服务接口* @author louluan*/public interface TicketService {//售票public void sellTicket();//问询public void inquire();//退票public void withdraw();}
文章插图
文章插图
package com.foo.proxy;/*** 车票代售点* @author louluan**/public class StationProxy implements TicketService {private Station station;public StationProxy(Station station){this.station = station;}@Overridepublic void sellTicket() {// 1.做真正业务前 , 提示信息this.showAlertInfo("××××您正在使用车票代售点进行购票 , 每张票将会收取5元手续费!××××");// 2.调用真实业务逻辑station.sellTicket();// 3.后处理this.takeHandlingFee();this.showAlertInfo("××××欢迎您的光临 , 再见!××××\n");}@Overridepublic void inquire() {// 1做真正业务前 , 提示信息this.showAlertInfo("××××欢迎光临本代售点 , 问询服务不会收取任何费用 , 本问询信息仅供参考 , 具体信息以车站真实数据为准!××××");// 2.调用真实逻辑station.inquire();// 3 。 后处理this.showAlertInfo("××××欢迎您的光临 , 再见!××××\n");}@Overridepublic void withdraw() {// 1 。 真正业务前处理this.showAlertInfo("××××欢迎光临本代售点 , 退票除了扣除票额的20%外 , 本代理处额外加收2元手续费!××××");// 2.调用真正业务逻辑station.withdraw();// 3.后处理this.takeHandlingFee();}/** 展示额外信息*/private void showAlertInfo(String info) {System.out.println(info);}/** 收取手续费*/private void takeHandlingFee() {System.out.println("收取手续费 , 打印发票 。。。。。 \n");}}
文章插图
由于我们现在不希望静态地有StationProxy类存在 , 希望在代码中 , 动态生成器二进制代码 , 加载进来 。 为此 , 使用Javassist开源框架 , 在代码中动态地生成StationProxy的字节码:
package com.foo.proxy;import java.lang.reflect.Constructor;import javassist.*;public class Test {public static void main(String[] args) throws Exception {createProxy();}/** 手动创建字节码*/private static void createProxy() throws Exception{ClassPool pool = ClassPool.getDefault();CtClass cc = pool.makeClass("com.foo.proxy.StationProxy");//设置接口CtClass interface1 = pool.get("com.foo.proxy.TicketService");cc.setInterfaces(new CtClass[]{interface1});//设置FieldCtField field = CtField.make("private com.foo.proxy.Station station;", cc);cc.addField(field);CtClass stationClass = pool.get("com.foo.proxy.Station");CtClass[] arrays = new CtClass[]{stationClass};CtConstructor ctc = CtNewConstructor.make(arrays,null,CtNewConstructor.PASS_NONE,null,null, cc);//设置构造函数内部信息ctc.setBody("{this.station=$1;}");cc.addConstructor(ctc);//创建收取手续 takeHandlingFee方法CtMethod takeHandlingFee = CtMethod.make("private void takeHandlingFee() {}", cc);takeHandlingFee.setBody("System.out.println(\"收取手续费 , 打印发票 。。。。。 \");");cc.addMethod(takeHandlingFee);//创建showAlertInfo 方法CtMethod showInfo = CtMethod.make("private void showAlertInfo(String info) {}", cc);showInfo.setBody("System.out.println($1);");cc.addMethod(showInfo);//sellTicketCtMethod sellTicket = CtMethod.make("public void sellTicket(){}", cc);sellTicket.setBody("{this.showAlertInfo(\"××××您正在使用车票代售点进行购票 , 每张票将会收取5元手续费!××××\");"+ "station.sellTicket();"+ "this.takeHandlingFee();"+ "this.showAlertInfo(\"××××欢迎您的光临 , 再见!××××\");}");cc.addMethod(sellTicket);//添加inquire方法CtMethod inquire = CtMethod.make("public void inquire() {}", cc);inquire.setBody("{this.showAlertInfo(\"××××欢迎光临本代售点 , 问询服务不会收取任何费用 , 本问询信息仅供参考 , 具体信息以车站真实数据为准!××××\");"+ "station.inquire();"+ "this.showAlertInfo(\"××××欢迎您的光临 , 再见!××××\");}");cc.addMethod(inquire);//添加widthraw方法CtMethod withdraw = CtMethod.make("public void withdraw() {}", cc);withdraw.setBody("{this.showAlertInfo(\"××××欢迎光临本代售点 , 退票除了扣除票额的20%外 , 本代理处额外加收2元手续费!××××\");"+ "station.withdraw();"+ "this.takeHandlingFee();}");cc.addMethod(withdraw);//获取动态生成的classClass c = cc.toClass();//获取构造器Constructor constructor= c.getConstructor(Station.class);//通过构造器实例化TicketService o = (TicketService)constructor.newInstance(new Station());o.inquire();cc.writeFile("D://test");}}上述代码执行过后 , 会产生StationProxy的字节码 , 并且用生成字节码加载如内存创建对象 , 调用inquire()方法 , 会得到以下结果:
- 中国|浅谈5G移动通信技术的前世和今生
- 芯片|华米GTS2mini和红米手表哪个好 参数功能配置对比
- 桌面|日常使用的软件及网站分享 篇一:几个动态壁纸软件和静态壁纸网站:助你美化你的桌面
- 华为|台积电、高通、华为、小米接连宣布!美科技界炸锅:怎么会这样!
- 二维码|村网通?澳大利亚一州推出疫情追踪二维码 还考虑采用人脸识别和地理定位
- 不到|苹果赚了多少?iPhone12成本不到2500元,华为和小米的利润呢?
- 机器人|网络里面的假消息忽悠了非常多的小喷子和小机器人
- 华为|骁龙870和骁龙855区别都是7nm芯片吗 性能对比评测
- 花15.5亿元与中粮包装握手言和 加多宝离上市又进一步?|15楼财经 | 清远加多宝
- 究竟|免费的OPPO R1电视究竟怎么样
