求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
Java静动态代理模式示例
 

发布于2012-6-11

 

静态代理模式中,真实角色必须是事先已经存在的,并将其作为代理对象的内部属性,并且真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀。那么,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。

设计模式

1.静态代理模式

使用场合:

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

涉及的角色:

抽象角色:

声明真实对象和代理对象的共同接口;

代理角色:

代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。

真实角色:

代理角色所代表的真实对象,是我们最终要引用的对象。

最好的老师是代码,下面是本人敲的一个静态代理代码示例?

Java代码

    package com;    
    /**   
     * 车站接口-【抽象角色】   
     *    
     * @author abing   
     *    
     */    
    interface Station {    
        void sellTicks();// 卖票    
        void transport();// 运输乘客    
    }    
    /**   
     * 火车站实现类-【具体角色】   
     *    
     * @author abing   
     *    
     */    
    class TrainStationImpl implements Station {    
        @Override    
        public void sellTicks() {    
            System.out.println("TrainStation  sell tickets");    
        }    
        @Override    
        public void transport() {    
            System.out.println("TrainStation  transport passenger");       
        }    
    }    
    /**   
     * 该类做为火车站的一个代理直接供客户端调用-【代理角色】   
     *    
     * @author abing   
     *    
     */    
    class StationProxy implements Station {    
        Station sta = new TrainStationImpl();    
        @Override    
        public void sellTicks() {    
            sta.sellTicks();//代理类中调用真实角色的方法。    
        }    
        public void otherOperate() {    
            System.out.println("do some other things...");    
        }    
        @Override    
        public void transport() {    
            System.out.println("StationProxy can not transport");    
        }    
    }    
    /**   
     * 客户端测试类   
     *    
     * @author abing   
     *    
     */    
    public class StaticProxyDemo {    
        public static void main(String[] args) {    
            Station station = new StationProxy();//客户端直接操作代理类,避免了客户端与真实类的直接交涉    
            station.sellTicks();    
        }    
    } 

2.动态代理模式

静态代理模式中,真实角色必须是事先已经存在的,并将其作为代理对象的内部属性,并且真实角色必须对应一个代理角色,如果大量使用会导致类的急剧膨胀。那么,如果事先并不知道真实角色,该如何使用代理呢?这个问题可以通过Java的动态代理类来解决。
动态代理必需用到以下两个类。

(1). Interface InvocationHandler:该接口中仅定义了一个方法Object:invoke(Object obj,Method method, Object[] args)。用于完成真实角色中方法的调用

(2).Proxy:该类即为动态代理类,作用类似于静态代理模式的代理类

最好的老师是代码,下面是本人敲的一个动态代理代码示例

Java代码

    package com.proxy;    
    import java.lang.reflect.InvocationHandler;    
    import java.lang.reflect.Method;    
    import java.lang.reflect.Proxy;    
    /**   
     * 车站接口-【抽象角色】   
     * @author abing   
     *   
     */    
    interface Station {    
        void sellTicks();// 卖票    
    }    
    /**   
     * 火车站实现类-【具体角色】   
     * @author abing   
     *   
     */    
    class TrainStationImpl implements Station {    
        @Override    
        public void sellTicks() {    
            System.out.println("TrainStation  sell tickets");    
        }    
    }    
    /**   
     * 使用动态代理模式必须实现InvocationHandler接口,该接口中仅定义了一个方法:   
     * invoke(Object obj,Method method, Object[] args)。   
     * 在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组   
     *    
     * @author abing   
     *   
     */    
    class InvocationHandlerImpl implements InvocationHandler {    
        Object proxyobj;    
        public InvocationHandlerImpl(Object object) {    
            this.proxyobj = object;    
        }    
        @Override    
        public Object invoke(Object obj, Method method, Object[] args)    
                throws Throwable {    
            System.out.println("start doing  .........");    
            method.invoke(proxyobj, args);//调用被代理对象proxyobj的方法method,传入一个参数组args    
            System.out.println("stop doing  .........");    
            return null;    
        }    
    }    
    /**   
     * 客户端测试类   
     * @author abing   
     *   
     */    
    public class DynamicProxyDemo {    
        public static void main(String[] args) {    
            Station stationImpl = new TrainStationImpl();//将要被代理的真实对象    
            /**   
             * 动态代理就好处在这里,不管这里是要代理什么对象,I   
             * nvocationHandlerImpl与Proxy中代码都不必改变,   
             * 都是用下面同样的方式去产生代理对象   
             */    
            InvocationHandler handler = new InvocationHandlerImpl(stationImpl);
            //用InvocationHandler的实现类包装真实的被代理角色    
            ClassLoader loader = handler.getClass().getClassLoader();
            //获取当期那java程序的类装在器Classloadler    
            Class[] interfaces = stationImpl.getClass().getInterfaces();
            //获取被代理角色实现的所有接口    
            /**   
             * Proxy类是动态代理模式涉及到的另一个重要的类,该类即为动态代理类,
             *作用类似于静态代理模式中的代理类StationProxy,   
             * 它有一个重要方法tatic Object newProxyInstance(ClassLoader loader, Class[] interfaces, 
             *InvocationHandler h):返回代理类的一个实例。   
             * 其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组,
             *传递此参数以使产生的代理对象可以当做真实类任意实现接口的子类来用,   
             * h是调用处理器InvocationHandler。    
             */    
            Station station = (Station) Proxy.newProxyInstance(loader, interfaces,handler);    
            station.sellTicks();//将会去执行DynamicProxy的invoke方法,完成对目标对象方法的调用    
        }    
    } 

 


相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践
 
分享到
 
 
     


重构-使代码更简洁优美
Visitor Parttern
由表及里看模式
设计模式随笔系列
深入浅出设计模式-介绍
.NET中的设计模式
更多...   

相关培训课程

J2EE设计模式和性能调优
应用模式设计Java企业级应用
设计模式原理与应用
J2EE设计模式指南
单元测试+重构+设计模式
设计模式及其CSharp实现


某电力公司 设计模式原理
蓝拓扑 设计模式原理及应用
卫星导航 UML & OOAD
汤森路透研发中心 UML& OOAD
中达电通 设计模式原理
西门子 嵌入式设计模式
更多...