码迷,mamicode.com
首页 > 其他好文 > 详细

代理模式

时间:2018-03-21 15:04:48      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:问题   private   str   lan   util   targe   代理类   proxy   stat   

定义:为其他对象提供一种代理以控制对这个对象的访问。代理对象起到中介作用,可去掉功能服务或增加额外的服务(火车票代售处)。 
远程代理(客户端服务器模式) 
虚拟代理(网站图片延迟加载) 
保护代理(控制用户的访问权限) 
智能引用代理(火车票代售处) 

静态代理

定义:代理和被代理对象在代理之前是确定的,它们都实现相同的接口或者继承相同的抽象类。

1. 没用代理模式之前 

1 package com.sakura.proxy;
2 
3 /**
4  * Created by sakura on 2018/3/21.
5  */
6 public interface Moveable {
7     void move();
8 }
 1 package com.sakura.proxy;
 2 
 3 import java.util.Random;
 4 
 5 /**
 6  * Created by sakura on 2018/3/21.
 7  */
 8 public class Car implements Moveable{
 9     @Override
10     public void move() {
11         long start=System.currentTimeMillis();
12         System.out.println("汽车开始行驶...");
13         //实现开车
14         try {
15             Thread.sleep(new Random().nextInt(1000));
16             System.out.println("汽车行驶中...");
17         } catch (InterruptedException e) {
18             e.printStackTrace();
19         }
20         long end=System.currentTimeMillis();
21         System.out.println("汽车结束行驶...汽车行驶时间:"+(end-start)+"毫秒!");
22     }
23 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class Client {
 7     public static void main(String[] args) {
 8         Car car = new Car();
 9         car.move();
10     }
11 }
12 /*
13 汽车开始行驶...
14 汽车行驶中...
15 汽车结束行驶...汽车行驶时间:482毫秒!
16  */

2. 用了代理模式(继承)之后 

1 package com.sakura.proxy;
2 
3 /**
4  * Created by sakura on 2018/3/21.
5  */
6 public interface Moveable {
7     void move();
8 }
 1 package com.sakura.proxy;
 2 
 3 import java.util.Random;
 4 
 5 /**
 6  * Created by sakura on 2018/3/21.
 7  */
 8 public class Car implements Moveable{
 9     @Override
10     public void move() {
11         //实现开车
12         try {
13             Thread.sleep(new Random().nextInt(1000));
14             System.out.println("汽车行驶中...");
15         } catch (InterruptedException e) {
16             e.printStackTrace();
17         }
18     }
19 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class Car2 extends Car {
 7     @Override
 8     public void move(){
 9         long start=System.currentTimeMillis();
10         System.out.println("汽车开始行驶...");
11         super.move();
12         long end=System.currentTimeMillis();
13         System.out.println("汽车结束行驶...汽车行驶时间:"+(end-start)+"毫秒!");
14     }
15 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class Client {
 7     public static void main(String[] args) {
 8         Moveable m=new Car2();
 9         m.move();
10     }
11 }
12 /*
13 汽车开始行驶...
14 汽车行驶中...
15 汽车结束行驶...汽车行驶时间:795毫秒!
16  */

3. 用了代理模式(组合)之后 

1 package com.sakura.proxy;
2 
3 /**
4  * Created by sakura on 2018/3/21.
5  */
6 public interface Moveable {
7     void move();
8 }
 1 package com.sakura.proxy;
 2 
 3 import java.util.Random;
 4 
 5 /**
 6  * Created by sakura on 2018/3/21.
 7  */
 8 public class Car implements Moveable{
 9     @Override
10     public void move() {
11         //实现开车
12         try {
13             Thread.sleep(new Random().nextInt(1000));
14             System.out.println("汽车行驶中...");
15         } catch (InterruptedException e) {
16             e.printStackTrace();
17         }
18     }
19 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class Car2 implements Moveable {
 7     public Car2(Car car){
 8         super();
 9         this.car=car;
10     }
11     private Car car;
12 
13     @Override
14     public void move() {
15         long start=System.currentTimeMillis();
16         System.out.println("汽车开始行驶...");
17         car.move();
18         long end=System.currentTimeMillis();
19         System.out.println("汽车结束行驶...汽车行驶时间:"+(end-start)+"毫秒!");
20     }
21 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class Client {
 7     public static void main(String[] args) {
 8         Car car=new Car();
 9         Moveable m=new Car2(car);
10         m.move();
11     }
12 }
13 /*
14 汽车开始行驶...
15 汽车行驶中...
16 汽车结束行驶...汽车行驶时间:360毫秒!
17  */

相比继承方式而言,组合方式扩展性更好。 

加上日志功能:

1 package com.sakura.proxy;
2 
3 /**
4  * Created by sakura on 2018/3/21.
5  */
6 public interface Moveable {
7     void move();
8 }
 1 package com.sakura.proxy;
 2 
 3 import java.util.Random;
 4 
 5 /**
 6  * Created by sakura on 2018/3/21.
 7  */
 8 public class Car implements Moveable{
 9     @Override
10     public void move() {
11         //实现开车
12         try {
13             Thread.sleep(new Random().nextInt(1000));
14             System.out.println("汽车行驶中...");
15         } catch (InterruptedException e) {
16             e.printStackTrace();
17         }
18     }
19 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class CarTimeProxy implements Moveable {
 7     public CarTimeProxy(Moveable m){
 8         super();
 9         this.m=m;
10     }
11     private Moveable m;
12     @Override
13     public void move() {
14         long start=System.currentTimeMillis();
15         System.out.println("汽车开始行驶...");
16         m.move();
17         long end=System.currentTimeMillis();
18         System.out.println("汽车结束行驶...汽车行驶时间:"+(end-start)+"毫秒!");
19     }
20 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class CarLogProxy implements Moveable {
 7     public CarLogProxy(Moveable m){
 8         super();
 9         this.m=m;
10     }
11     private Moveable m;
12     @Override
13     public void move() {
14         System.out.println("日志开始...");
15         m.move();
16         System.out.println("日志结束...");
17     }
18 }
 1 package com.sakura.proxy;
 2 
 3 /**
 4  * Created by sakura on 2018/3/21.
 5  */
 6 public class Client {
 7     public static void main(String[] args) {
 8         Car car=new Car();
 9         CarTimeProxy ctp=new CarTimeProxy(car);
10         CarLogProxy clp=new CarLogProxy(ctp);
11         clp.move();
12     }
13 }
14 /*
15 日志开始...
16 汽车开始行驶...
17 汽车行驶中...
18 汽车结束行驶...汽车行驶时间:228毫秒!
19 日志结束...
20  */

但是问题来了,如果这会汽车变成火车了,难道又要重写一个TrainTimeProxy和TrainLogProxy吗,能不能只写一个TimeProxy和LogProxy实现对各种车的代理呢?

动态代理

1. JDK动态代理 

只能代理实现了接口的类,没有实现接口的类不能实现JDK的动态代理。 

动态代理实现步骤:

创建一个实现接口InvocationHandler的类,它必须实现invoke方法

创建被代理的类以及接口

调用Proxy的静态方法,创建一个代理类newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

通过代理调用方法

1 package com.sakura.proxy;
2 
3 /**
4  * Created by sakura on 2018/3/21.
5  */
6 public interface Moveable {
7     void move();
8 }
 1 package com.sakura.proxy;
 2 
 3 import java.util.Random;
 4 
 5 /**
 6  * Created by sakura on 2018/3/21.
 7  */
 8 public class Car implements Moveable{
 9     @Override
10     public void move() {
11         //实现开车
12         try {
13             Thread.sleep(new Random().nextInt(1000));
14             System.out.println("汽车行驶中...");
15         } catch (InterruptedException e) {
16             e.printStackTrace();
17         }
18     }
19 }
 1 package com.sakura.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  * Created by sakura on 2018/3/21.
 8  */
 9 public class TimeHandler implements InvocationHandler {
10     private Object target;
11     public TimeHandler(Object target){
12         super();
13         this.target=target;
14     }
15     @Override
16     //proxy:代理类  method:被代理的方法  args:方法的参数数组
17     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
18         long start=System.currentTimeMillis();
19         System.out.println("汽车开始行驶...");
20         method.invoke(target);
21         long end=System.currentTimeMillis();
22         System.out.println("汽车结束行驶...汽车行驶时间:"+(end-start)+"毫秒!");
23         return null;
24     }
25 }
 1 package com.sakura.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Proxy;
 5 
 6 /**
 7  * Created by sakura on 2018/3/21.
 8  */
 9 public class Test {
10     public static void main(String[] args) {
11         Car car=new Car();
12         InvocationHandler h= new TimeHandler(car);
13         Class<?> cls=car.getClass();
14         //loader:类加载器  interfaces:实现接口  h:InvocationHandler
15         Moveable m= (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),h);
16         m.move();
17     }
18 }
19 /*
20 汽车开始行驶...
21 汽车行驶中...
22 汽车结束行驶...汽车行驶时间:171毫秒!
23  */

 2. cglib动态代理 

针对类来实现代理的,对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用(继承实现,不能代理被final修饰的类)。

需要导入一个名为cglib-nodep-2.2.jar的包。

代理模式

标签:问题   private   str   lan   util   targe   代理类   proxy   stat   

原文地址:https://www.cnblogs.com/sakura1027/p/8616778.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!