当前位置: 首页 > news >正文

培训行业网站建设15年做哪些网站致富

培训行业网站建设,15年做哪些网站致富,中国建设银行官网站e路护航,学做网站的书目录 十四、GoF之代理模式 14.1对代理模式的理解 14.2静态代理 14.3动态代理 14.3.1JDK动态代理 14.3.2CGLIB动态代理 十四、GoF之代理模式 14.1对代理模式的理解 场景#xff1a;拍电影的时候#xff0c;替身演员去代理演员完成表演。这就是一个代理模式。 演员为什…目录 十四、GoF之代理模式 14.1对代理模式的理解 14.2静态代理 14.3动态代理 14.3.1JDK动态代理 14.3.2CGLIB动态代理 十四、GoF之代理模式 14.1对代理模式的理解 场景拍电影的时候替身演员去代理演员完成表演。这就是一个代理模式。 演员为什么要找替身呢为什么要使用代理模式 怕自己受伤。保护自己 自己完成不了高难度动作。功能增强 在java程序中代理模式的作用 当一个对象需要受到保护的时候可以考虑使用代理对象去完成某个行为。 需要给某个对象的功能进行增强的时候可以考虑找一个代理进行增强。 A对象无法和B对象直接交互也可以使用代理模式来解决。 代理模式中有三个角色 目标对象演员 代理对象替身演员 目标对象和代理对象的公共接口。演员和替身演员应该具有相同的行为动作 为什么演员和替身演员要有相同的行为动作呢 不想让观众知道是替身演员这里的观众其实就是“客户端程序”。 使用代理模式对于客户端程序来说客户端是无法察觉到的客户端在使用代理对象的时候就像在使用目标对象。 代理模式是GoF23种设计模式之一属于结构化设计模式。 代理模式在代码实现上包括两种形式 静态代理 动态代理 14.2静态代理 OrderService接口 package com.hhb.proxy.service; ​ //订单业务接口 public interface OrderService {//代理对象和目标对象的公共接口//生产订单void generate(); ​//修改订单信息void modify(); ​//查看订单详情void detail(); } OrderServiceImpl package com.hhb.proxy.service; ​ public class OrderServiceImpl implements OrderService {/*** 问题统计所有业务接口的每一个业务方法的耗时。* 解决方案一硬编码在每一个业务接口中的每一个业务方法中直接添加统计耗时的程序* 缺点1.违背OCP开闭原则 2.代码没有得到复用* 解决方案二编写业务类的子类让子类继承业务类对每个业务方法进行重写* 缺点1.虽然解决了OCP开闭原则但是代码耦合度很高因为采用了继承关系。*     2.代码没有得到复用* 解决方案三代理模式* 优点1.解决了OCP问题 2.采用代理模式的has a可以降低耦合度** 目前使用的是静态代理这个静态代理的缺点是类爆炸* 解决方法使用动态代理模式来解决这个问题。* 动态代理还是代理模式只不过添加了字节码生成技术可以在内存中为我们动态生成一个class字节码这个字节码就是代理类* 在内存中动态生成字节码代理类的技术叫做动态代理*/Overridepublic void generate() {//目标方法//模拟生成订单的耗时try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(订单已生成);} ​Overridepublic void modify() {//目标方法//模拟修改订单的耗时try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(订单已修改);} ​Overridepublic void detail() {//目标方法//模拟查询订单的耗时try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(请看订单详情);} } OrderServiceProxy package com.hhb.proxy.service; ​ //代理对象代理对象和目标对象要具有相同的行为就要实现同一个或同一些接口 //客户端在使用代理对象的时候就像在使用目标对象一样。 public class OrderServiceProxy implements OrderService {//将目标对象作为代理对象的一个属性这种关系叫做关联关系比继承关系的耦合度低//代理对象中含有目标对象的引用。关联关系has a//注意这里要写一个公共接口类型因为公共接口耦合度低private OrderService target;//这就是目标对象目标对象一定实现了OrderService接口//创建代理对象的时候传一个目标对象给代理对象。public OrderServiceProxy(OrderService target) {this.target target;} ​Overridepublic void generate() {//代理方法//增强long begin System.currentTimeMillis();//调用目标对象的目标方法target.generate();long end System.currentTimeMillis();System.out.println(耗时 (end - begin) );} ​Overridepublic void modify() {long begin System.currentTimeMillis();target.modify();long end System.currentTimeMillis();System.out.println(耗时 (end - begin) );} ​Overridepublic void detail() {long begin System.currentTimeMillis();target.detail();long end System.currentTimeMillis();System.out.println(耗时 (end - begin) );} } 客户端 package com.hhb.proxy.client; ​ import com.hhb.proxy.service.OrderServiceImpl; import com.hhb.proxy.service.OrderServiceProxy; ​ public class Test {public static void main(String[] args) {//创建目标对象OrderServiceImpl target new OrderServiceImpl();//创建代理对象OrderServiceProxy proxy new OrderServiceProxy(target);//调用代理对象的代理方法proxy.generate();proxy.modify();proxy.detail();} } 以上就是代理模式中的静态代理其中OrderService接口是代理类和目标类的共同接口。 OrderServiceImpl是目标类OrderServiceProxy是代理类。 14.3动态代理 在程序运行阶段在内存中动态生成代理类被称为动态代理目的是为了减少代理类的数量解决代码复用的问题。 在内存当中动态生成类的技术常见的包括 JDK动态代理技术只能代理接口。 CGLIB动态代理技术CGLIB是一个开源项目是一个强大的、高性能、高质量的Code生成类库它可以在运行期扩展Java类与实现Java接口。它既可以代理接口又可以代理类底层是通过继承的方式实现的。性能比JDK动态代理要好。底层有一个小而快的字节码处理框架ASM。 Javassist动态代理技术。 14.3.1JDK动态代理 OrderService接口 package com.hhb.proxy.service; ​ //订单业务接口 public interface OrderService {//代理对象和目标对象的公共接口//生产订单void generate(); ​//修改订单信息void modify(); ​//查看订单详情void detail(); } OrderServiceImpl package com.hhb.proxy.service; ​ public class OrderServiceImpl implements OrderService {Overridepublic void generate() {//目标方法//模拟生成订单的耗时try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(订单已生成);} ​Overridepublic void modify() {//目标方法//模拟修改订单的耗时try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(订单已修改);} ​Overridepublic void detail() {//目标方法//模拟查询订单的耗时try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(请看订单详情);} } 在动态代理中OrderServiceProxy代理类是可以动态生成的这个类不需要写直接写客户端程序即可。 Client package com.hhb.proxy.client; ​ import com.hhb.proxy.service.OrderService; import com.hhb.proxy.service.OrderServiceImpl; import com.hhb.proxy.service.TimerInvocationHandler; import com.hhb.proxy.util.ProxyUtil; ​ import java.lang.reflect.Proxy; ​ public class Client {//客户端程序public static void main(String[] args) {//创建目标对象OrderService target new OrderServiceImpl();//创建代理对象/* OrderService proxyObj (OrderService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new TimerInvocationHandler(target));*///使用工具类OrderService proxyObj (OrderService) ProxyUtil.newProxyInstance(target);//调用代理对象的代理方法proxyObj.modify();proxyObj.detail();proxyObj.generate();String name proxyObj.getName();System.out.println(name);} } 创建代理对象 newProxyInstance翻译为新建代理对象也就是说通过调用这个方法可以创建代理对象。本质上这个Proxy.newProxyInstance()方法的执行做了两件事 在内存中动态的生成了一个代理类的字节码class。 new对象了通过内存中生成的代理类这个代码实例化了代理对象。 关于newProxyInstance()方法的三个重要的参数 第一个参数ClassLoader loader 它是类加载器。在内存中生成的字节码也是class文件要执行也得先加载到内存当中。加载类就需要类加载器所以这里需要指定类加载器。并且JDK要求目标类的类加载器必须和代理类的类加载器使用同一个。 第二个参数Class?[] interfaces 代理类和目标类要实现同一个接口或同一些接口。 在内存中生成代理类的时候这个代理类是需要你告诉它实现哪些接口的。 第三个参数InvocationHandler h InvocationHandler 被翻译为调用处理器是一个接口。 在调用处理器接口中编写的就是增强代码。 既然是接口就要写接口的实现类。 TimerInvocationHandler package com.hhb.proxy.service; ​ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; ​ public class TimerInvocationHandler implements InvocationHandler {//目标对象private Object target; ​public TimerInvocationHandler(Object target) {this.target target;} ​Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//这个接口的作用是写增强代码long begin System.currentTimeMillis();//调用目标对象上的目标方法//方法四要素哪个对象哪个方法传什么参数返回什么值Object retValue method.invoke(target, args);long end System.currentTimeMillis();System.out.println(耗时 (end - begin) 毫秒);//注意这个invoke方法的返回值如果代理对象调用代理方法之后需要返回结果的话invoke方法必须将目标对象的目标方法执行结果继续返回return retValue;} } 为什么要强行要求你必须实现InvocationHandler接口 因为一个类实现接口就必须实现接口中的方法。 方法必须是invoke()因为JDK在底层调用invoke()方法的程序已经提前写好了。 注意invoke方法不是程序员调用的是JDK负责调用。 invoke方法什么时候被调用 当代理对象调用代理方法的时候注册在InvocationHandler调用处理器当中的invoke()方法被调用。 invoke方法的三个参数 invoke方法是JDK负责调用的所以JDK调用这个方法的时候会自动给我们传过来这三个参数可以在invoke方法的大括号中直接使用。 第一个参数Object proxy 代理对象的引用这个参数使用较少。 第二个参数Method method 目标对象上的目标方法。 第三个参数Object[] args 目标方法上的实参。 invoke方法执行过程中使用method来调用目标对象的目标方法。 工具类ProxyUtil package com.hhb.proxy.util; ​ import com.hhb.proxy.service.TimerInvocationHandler; ​ import java.lang.reflect.Proxy; ​ public class ProxyUtil {/*** 封装一个工具方法可以通过这个方法获取代理对象** param target* return*/public static Object newProxyInstance(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new TimerInvocationHandler(target));} } 14.3.2CGLIB动态代理 CGLIB既可以代理接口又可以代理类。底层采用继承的方式实现所以被代理的目标类不能使用final修饰。 引入依赖 dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.3.0/version /dependency UserService package com.hhb.proxy.service; ​ //目标类 public class UserService {//目标方法public boolean login(String username, String password) {System.out.println(系统正在验证身份);if (admin.equals(username) 123.equals(password)) {return true;}return false;} ​//目标方法public void logout() {System.out.println(系统正在退出);} } 使用CGLIB在内存中为UserService类生成代理类并创建对象 Client package com.hhb.proxy.client; ​ import com.hhb.proxy.service.TimerMethodInterceptor; import com.hhb.proxy.service.UserService; import net.sf.cglib.proxy.Enhancer; ​ public class Client {public static void main(String[] args) {//创建字节码增强器对象//这个对象是CGLIB库当中的核心对象就是依靠它来生成代理类Enhancer enhancer new Enhancer(); ​//告诉CGLIB父类是谁告诉CGLIB目标类是谁enhancer.setSuperclass(UserService.class); ​//设置回调(等同于JDK动态代理当中的调用处理器。InvocationHandler)//在CGLIB当中不是InvocatioHandler接口是方法拦截器MethodInterceptorenhancer.setCallback(new TimerMethodInterceptor()); ​//创建代理对象//1.在内存中生成UserService类的子类其实就是代理类的字节码。//2.创建代理对象UserService userServiceProxy (UserService) enhancer.create(); ​//调用代理对象的代理方法boolean succes userServiceProxy.login(admin, 123);System.out.println(succes ? 登录成功 : 登录失败); ​userServiceProxy.logout();} } 编写MethodInterceptor接口实现类 package com.hhb.proxy.service; ​ import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; ​ import java.lang.reflect.Method; ​ public class TimerMethodInterceptor implements MethodInterceptor {Overridepublic Object intercept(Object target, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {//前面增强long begin System.currentTimeMillis(); ​//调用目标对象的目标方法Object retValue methodProxy.invokeSuper(target, objects); ​//后面增强long end System.currentTimeMillis();System.out.println(耗时 (end - begin) 毫秒); ​return retValue;} }
http://www.dnsts.com.cn/news/22370.html

相关文章:

  • 苏州高端网站电商运营培训课程有哪些
  • 佛山市公司网站制作网站建设开发公司报价
  • 成都html5网站建设怎样做网站推广
  • 泰州专一做淘宝网站关键词优化的建议
  • 网站后台什么语做零售的外贸网站
  • 县区工会网站建设方案西城做网站
  • 万江区网站仿做实用的wordpress插件
  • 印刷厂网站模板北京门户网站制作公司
  • 成都 网站免费网站安全软件大全免费下载安装
  • 做购物商城网站设计服装设计公司英文
  • 如何自助建网站一站式建网站专业英文网站制作
  • 手机版企业网站网站建设预期达到的效果
  • 特产网站开发的目的莱芜网络公司
  • 企业网站 asp.net太湖县城乡建设局网站
  • 快速建设房产网站亚马逊周末可以视频认证吗
  • 广州制作外贸网站公司中国建筑集团2023招聘官网
  • 网站做常规优化投资者关系互动平台
  • 网站规划与设计一千字可以全部免费观看的软件
  • 网站优化 福州网站设计开发建设公司
  • 专业网站建设最新报价做网站需要哪些栏目
  • 贵州省公路建设有限公司网站深圳定制展会时间表
  • 成都html5网站设计一个网络空间如何做两个网站
  • 网站备案去哪注销怎么做网站关键词排名
  • 2019建一个什么网站最好wordpress小小工具
  • 房产网站建设机构什么网站可以找到做餐饮的会计
  • 五屏网站建设哪家有上海建设安全协会网站
  • 网络直播网站建设温州做高端网站公司排名
  • 珠海营销型网站哪家好网上做效果图网站有哪些
  • win7下asp.net网站发布摄影网页设计案例
  • 网站建设算软件还是硬件如何修改网站后台时间