Java设计模式(05-- 代理模式模式 )
2017-02-23 11:03
507 查看
学习代理模式之前需要了解的内容
1)面向对象的设计思想 2)了解多态概念 3)了解反射原理
本课程包括代理模式的概念及其分类、了解代理模式开发中的应用场景、掌握代理模式的实现方式、
理解JDK动态代理的实现。
代理模式的定义:
为其他对象提供一种代理以控制对这个对象的访问,代理对象起到中介作用,可去掉功能服务或者增加
额外的服务。
分类:
1)远程代理:为不同地理的对象提供局域网代表对象,类似客户端和服务器这种模式。
2)虚拟代理:根据需求将资源消耗很大的对象进行延迟处理,真正需要的时候再进行创建。(如一篇文章
的图片很大,我们可以用代替让图片进行延迟加载)
3)保护代理:如论坛的访问权限,我们就可以通过保护代理来实现。
4)智能引用代理:最常用的代理,一般都是需要在代理的服务之前增添某些功能。
以智能引用代理为例其实现方式有静态代理和动态代理两种方式。
静态代理:代理和被代理对象在代理之前都是确定的,他们都是实现了相同的接口或者继承了相同的抽象类。
实现静态方法可以通过继承的方式和聚合的方式来实现
实例:对行驶的汽车进行计时服务。
目标接口(被代理类和代理类都需要实现的接口类):Moveable
被代理类(提供汽车行驶功能)Car
使用继承方式实现静态代理的代理类 CarExtends
使用聚合方式实现静态代理的代理类 Car3
继承方式和聚合方式哪种更好??
现实情况我们需要在代理服务前后做很多功能的叠加,如在move()方法前后不仅需要做计时功能还需要权限功能,日志记录服务。
而Java是单继承的,继承的方式实现静态代理来达到功能的叠加,继承将会无限膨胀下去,因此并不可取。
聚合的方式需要代理类和被代理类都实现相同的接口。
现在我们用聚合的方式完成汽车行驶计时和日志功能的叠加
时间代理类 CarTimeProxy
View Code
思考作业:
我们用JDK完成了对Car运行时间的记录,另外我们需要在进行叠加记录日志的功能。
CgLib实现动态代理
首先需要引入Cglib的jar包 cglib-nodep-2.2.jar
实例代码:
被代理类 Train
Cglib代理类 CglibProxy
测试代码见上面的客户端测试类 。
智能引用代理在实际开发中应用最广泛,可以进行日志处理,权限管理,事务管理。
动态代理在面向切面编程(AOP)非常有用。
模拟JDK动态代理实现原理(未完待续················)
1)面向对象的设计思想 2)了解多态概念 3)了解反射原理
本课程包括代理模式的概念及其分类、了解代理模式开发中的应用场景、掌握代理模式的实现方式、
理解JDK动态代理的实现。
代理模式的定义:
为其他对象提供一种代理以控制对这个对象的访问,代理对象起到中介作用,可去掉功能服务或者增加
额外的服务。
分类:
1)远程代理:为不同地理的对象提供局域网代表对象,类似客户端和服务器这种模式。
2)虚拟代理:根据需求将资源消耗很大的对象进行延迟处理,真正需要的时候再进行创建。(如一篇文章
的图片很大,我们可以用代替让图片进行延迟加载)
3)保护代理:如论坛的访问权限,我们就可以通过保护代理来实现。
4)智能引用代理:最常用的代理,一般都是需要在代理的服务之前增添某些功能。
以智能引用代理为例其实现方式有静态代理和动态代理两种方式。
静态代理:代理和被代理对象在代理之前都是确定的,他们都是实现了相同的接口或者继承了相同的抽象类。
实现静态方法可以通过继承的方式和聚合的方式来实现
实例:对行驶的汽车进行计时服务。
目标接口(被代理类和代理类都需要实现的接口类):Moveable
1 package com.imooc.pattern.proxy; 2 3 public interface Moveable { 4 void move(); 5 }
被代理类(提供汽车行驶功能)Car
1 package com.imooc.pattern.proxy; 2 3 import java.util.Random; 4 5 public class Car implements Moveable { 6 7 public void move() { 8 try { 9 Thread.sleep(new Random().nextInt(1000)); 10 System.out.println("汽车行驶中······"); 11 } catch (InterruptedException e) { 12 e.printStackTrace(); 13 } 14 } 15 16 }
使用继承方式实现静态代理的代理类 CarExtends
1 package com.imooc.pattern.proxy; 2 3 /** 4 * 通过继承的方式实现静态代理 5 * CarExtends通过重写move方法,调用super.move()方法实现了对父类Car的代理, 6 * 同时在super.move()方法前后加入了自己提供的额外服务 7 * @author zplogo 8 * 9 */ 10 public class CarExtends extends Car { 11 12 public void move() { 13 long startTime = System.currentTimeMillis(); 14 System.out.println("汽车开始行驶······"); 15 super.move(); 16 long endTime = System.currentTimeMillis(); 17 System.out.println("汽车终止行驶····本次行程共花费时间:"+(endTime-startTime)+"毫秒"); 18 } 19 20 }
使用聚合方式实现静态代理的代理类 Car3
1 package com.imooc.pattern.proxy; 2 3 /** 4 * 使用聚合的方式实现静态代理 5 * 聚合就是在一个类中需要调用另一个对象,通过构造方法进行注入,然后在实现接口的方法中调用被代理对象的方法 6 * 在该方法前后加入自己的逻辑功能 7 * @author zplogo 8 * 9 */ 10 public class Car3 implements Moveable { 11 12 private Car car; 13 14 public Car3(Car car) { 15 super(); 16 this.car = car; 17 } 18 19 public void move() { 20 long startTime = System.currentTimeMillis(); 21 System.out.println("汽车开始行驶····计时开始··"); 22 car.move(); 23 long endTime = System.currentTimeMillis(); 24 System.out.println("汽车终止行驶····本次行程共花费时间:"+(endTime-startTime)+"毫秒"); 25 } 26 27 }
继承方式和聚合方式哪种更好??
现实情况我们需要在代理服务前后做很多功能的叠加,如在move()方法前后不仅需要做计时功能还需要权限功能,日志记录服务。
而Java是单继承的,继承的方式实现静态代理来达到功能的叠加,继承将会无限膨胀下去,因此并不可取。
聚合的方式需要代理类和被代理类都实现相同的接口。
现在我们用聚合的方式完成汽车行驶计时和日志功能的叠加
时间代理类 CarTimeProxy
1 package com.imooc.pattern.jdkproxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5 6 import com.imooc.pattern.proxy.Car; 7 import com.imooc.pattern.proxy.Moveable; 8 9 public class JdkProxyTest { 10 11 public static void main(String[] args) { 12 Car car = new Car(); 13 InvocationHandler h = new TimeHandler(car); 14 Class<?> cls=car.getClass(); 15 /* 16 * loader 被代理类的类加载器 17 * interfaces 实现接口 18 * h InvocationHandler 19 */ 20 Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces() , h); 21 m.move(); 22 } 23 24 }
View Code
思考作业:
我们用JDK完成了对Car运行时间的记录,另外我们需要在进行叠加记录日志的功能。
CgLib实现动态代理
首先需要引入Cglib的jar包 cglib-nodep-2.2.jar
实例代码:
被代理类 Train
1 package com.imooc.pattern.cglibproxy; 2 3 public class Train { 4 public void move(){ 5 System.out.println("火车行驶中········"); 6 } 7 }
Cglib代理类 CglibProxy
1 package com.imooc.pattern.cglibproxy; 2 3 import java.lang.reflect.Method; 4 5 import net.sf.cglib.proxy.Enhancer; 6 import net.sf.cglib.proxy.MethodInterceptor; 7 import net.sf.cglib.proxy.MethodProxy; 8 9 public class CglibProxy implements MethodInterceptor { 10 11 private Enhancer enhancer = new Enhancer();//创建代理类的属性 12 13 public Object getProxy(Class clazz){ 14 enhancer.setSuperclass(clazz);//设置创建子类的类(被代理类) 15 enhancer.setCallback(this); 16 return enhancer.create(); 17 } 18 19 /* 20 * 拦截所有目标类的方法的调用 21 * object 目标类的实例 22 * m 目标方法反射的对象 23 * args 方法的参数 24 * proxy 代理类的实例 25 */ 26 @Override 27 public Object intercept(Object object, Method m, Object[] args, 28 MethodProxy proxy) throws Throwable { 29 System.out.println("开始记录日志·······"); 30 //代理类调用父类的方法 31 proxy.invokeSuper(object, args); 32 System.out.println("结束记录日志·······"); 33 return null; 34 } 35 36 }
测试代码见上面的客户端测试类 。
智能引用代理在实际开发中应用最广泛,可以进行日志处理,权限管理,事务管理。
动态代理在面向切面编程(AOP)非常有用。
模拟JDK动态代理实现原理(未完待续················)
相关文章推荐
- java设计模式--代理及其动态代理--05
- Java设计模式圣经连载(05)-代理模式
- 基于Java的代理设计模式
- 基于Java的代理设计模式
- Java设计模式:单态模式,工厂模式,代理模式,观察者模式示例
- java 设计模式 学习笔记(6) 代理模式
- JAVA 设计模式 代理Proxy模式 一
- 基于Java的代理设计模式
- 深入浅出基于Java的代理设计模式
- JAVA设计模式之代理模式
- [转]转个经典的帖子:说故事学设计模式之-Java动态代理模式
- java设计模式-代理模式
- 深入浅出基于Java的代理设计模式
- java设计模式_代理模式_动态代理(带例子)
- Java设计模式:Proxy(代理)
- 设计模式:用Java动态代理实现AOP
- Java设计模式-----Proxy模式(静态代理)
- Java设计模式-----Proxy模式(动态代理)
- Java设计模式之虚拟代理模式
- JAVA设计模式之代理模式(转)