码迷,mamicode.com
首页 > 编程语言 > 详细

Java代理模式

时间:2018-09-09 16:49:23      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:his   result   ref   object   ade   print   string   voc   invoke   

代理模式学习

  • 基本概念
  • 具体实现方式

 

一基本概念

为其他对象提供一种代理,以控制对这个对象的访问。代理对象起到中介作用,可去掉功能服务或增加额外的服务。

 

二实现方式

  • 静态代理
  • 动态代理

 

1、静态代理

静态代理实现方式有:继承和实现接口两种方式,通常会选用后者。

 1 package cn.np.proxy.staticproxy;
 2 
 3 /**
 4  * @author np
 5  * @date 2018/9/9
 6  * 目标对象实现接口
 7  */
 8 public interface TicketHandler {
 9     void saleTicket();
10 }
 1 package cn.np.proxy.staticproxy;
 2 
 3 /**
 4  * @author np
 5  * @date 2018/9/9
 6  * 目标对象实现类
 7  */
 8 public class TrainStation implements TicketHandler{
 9 
10     @Override
11     public void saleTicket() {
12         System.out.println("销售火车票-出票来自火车站");
13     }
14 }
 1 package cn.np.proxy.staticproxy;
 2 
 3 /**
 4  * @author np
 5  * @date 2018/9/9
 6  * 静态代理类
 7  */
 8 public class TicketProxy implements TicketHandler{
 9 
10     private TrainStation trainStation;
11 
12     public TicketProxy(){
13 
14     }
15 
16     public TicketProxy(TrainStation trainStation){
17         this.trainStation=trainStation;
18     }
19 
20     @Override
21     public void saleTicket() {
22         System.out.println("出票前-代理类");
23         if(null!=trainStation){
24             trainStation.saleTicket();
25         }
26         System.out.println("出票后-代理类");
27     }
28 }
 1 package cn.np.proxy.staticproxy;
 2 
 3 /**
 4  * @author np
 5  * @date 2018/9/9
 6  *
 7  * 静态代理测试
 8  */
 9 public class Client {
10 
11     public static void main(String[] args){
12         TrainStation trainStation=new TrainStation();
13         trainStation.saleTicket();
14 
15         TicketProxy ticketProxy=new TicketProxy(trainStation);
16         ticketProxy.saleTicket();
17     }
18 }

输出结果:

销售火车票-出票来自火车站
出票前-代理类
销售火车票-出票来自火车站
出票后-代理类

总结:

优点:不对对象进行修改的前提下,对目标对象进行扩展和拦截;

缺点:因为代理对象需要实现与目标对象一样的接口,会导致代理类维护复杂,同一逻辑的代理类需要实现不同类型的目标对象的接口,如以上例子中需要代理销售飞机票、汽车票等。

 

2、动态代理

动态在内存中得到目标对象的实例,执行目标方法。实现方式有两种:JDK动态代理和Cglib动态代理,JDK动态代理只能代理实现类接口的类;cglib动态代理是针对类来实现的(继承)。

JDK动态代理实现的步骤:

  • 动态代理类实现接口java.lang.reflect.InvocationHandler
  • 创建被代理的类及接口
  • 调用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h),动态创建代理类
package cn.np.proxy.dynamic;

/**
 * @author np
 * @date 2018/9/9
 */
public interface TicketHandler {
    void saleTicket();
}


public interface LogHandler {

    void writeLog();
}

 

 1 package cn.np.proxy.dynamic;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  * @author np
 8  * @date 2018/9/9
 9  * 动态代理类
10  */
11 public class TicketDynamicProxy implements InvocationHandler {
12 
13     private Object target;
14 
15     public TicketDynamicProxy(Object object){
16         target=object;
17     }
18 
19     /**
20      * @param proxy 被代理对象
21      * @param method 被代理对象方法
22      * @param args 被代理对象方法参数
23      * @return
24      * @throws Throwable
25      */
26     @Override
27     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
28         System.out.println("动态代理-执行目标方法前");
29         Object result=method.invoke(target);
30         System.out.println("动态代理-执行目标方法后");
31         return result;
32     }
33 }
 1 package cn.np.proxy.dynamic;
 2 
 3 
 4 import java.util.Date;
 5 
 6 /**
 7  * @author np
 8  * @date 2018/9/9
 9  */
10 public class TrainStation implements TicketHandler,LogHandler{
11 
12     @Override
13     public void saleTicket() {
14         System.out.println("销售火车票-出票来自火车站");
15     }
16 
17     @Override
18     public void writeLog() {
19         System.out.println("记录日志,当前时间是:"+new Date().getTime());
20     }
21 }
 1 package cn.np.proxy.dynamic;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Proxy;
 5 
 6 /**
 7  * @author np
 8  * @date 2018/9/9
 9  */
10 public class Client {
11 
12     public static void main(String[] agrs){
13         TrainStation trainStation=new TrainStation();
14         Class<?> clz=trainStation.getClass();
15         Class<?>[] interfaces=clz.getInterfaces();
16 
17         InvocationHandler handler=new TicketDynamicProxy(trainStation);
18 
19         TicketHandler ticketHandler=(TicketHandler) Proxy.newProxyInstance(clz.getClassLoader(),interfaces,handler);
20         ticketHandler.saleTicket();
21 
22         LogHandler logHandler=(LogHandler) Proxy.newProxyInstance(clz.getClassLoader(),interfaces,handler);
23         logHandler.writeLog();
24 
25     }
26 }

输出结果:

动态代理-执行目标方法前
销售火车票-出票来自火车站
动态代理-执行目标方法后
动态代理-执行目标方法前
记录日志,当前时间是:1536478014151
动态代理-执行目标方法后

 

优点:代理类不需要和目标类实现同一个接口,增加了灵活性

缺点:代理对象不需要实现接口,但是目标对象一定要实现接口,否则无法使用JDK动态代理。  

 

Java代理模式

标签:his   result   ref   object   ade   print   string   voc   invoke   

原文地址:https://www.cnblogs.com/nox-np/p/9613884.html

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