代理模式(静态代理和动态代理)
来源:互联网 发布:centos 7图形界面安装 编辑:程序博客网 时间:2024/05/19 14:53
一、代理模式
代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
静态代理的一个代理只能代理一种类型,而且是在编译器就已经确定被代理的对象。而动态代理是在运行时,通过反射机制实现动态代理,并且能够代理各种类型的对象。
二、静态代理
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
静态代理的类图
静态代理代码(在这里只贴主要代码,源码附上链接地址,有兴趣的可以下载看看)
package StaticProxy;/** * @ClassName: Proxy * @Description: 代理类 * @author 张薄- huaxiangniaoyu0109@126.com * @date 2015年5月26日 下午2:52:10 */public class Proxy implements Subject {private RealSubject realSubject ;//在编译器就已经确定了具体的委托类public Proxy(RealSubject realSubject){this.realSubject =realSubject; }@Overridepublic void giveGift() {realSubject.giveGift();}}
静态代理类的缺点:当如果接口加一个方法(把上面所有的代码的注释给去掉),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。
三、动态代理
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
动态代理在Java中要想实现动态代理机制,需要java.lang.reflect.InvocationHandler 接口和java.lang.reflect.Proxy 类的支持。
java.lang.reflect.InvocationHandler接口的定义如下:
public interfaceInvocationHandler { public Object invoke(Object proxy, Methodmethod, Object[] args) throws Throwable;}
Objectproxy:被代理的对象(委托类)
Methodmethod:要调用的方法(委托类)
Object[]args:方法调用时所需要参数
java.lang.reflect.Proxy类的定义如下:——取得代理对象
public static ObjectnewProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
CLassLoaderloader:类的加载器(委托类)
Class<?>interfaces:得到全部的接口(委托类)
InvocationHandlerh:得到InvocationHandler接口的子类的实例(代理类)
大概看完这些,我们先来画一幅第一版的动态代理类图:
这是我第一版画的动态代理类图,为了显示动态代理的延迟加载,与真实的类解耦,我用了客户端,来表示运行时才会真正的去实例想要的真实类,动态代理类与真实类才会发生关系。但是,这个类图少了一些类,既然是类图,我们前面说的Proxy类就没有在这里表现出来。所以,我改进了第二版动态代理图:
这张图就显示出了Proxy和InvocationHandler类,并且将上面说的InvocationHandler和Proxy如何实现动态代理的原理也捎带出来了。
有人说,代码就是最好的老师,也许有些人对这张图还是不太理解,没关系,看代码就行(在这里只贴主要代码,源码附上链接地址,有兴趣的可以下载看看):
package DynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * @ClassName: DynamicProxy * @Description: 动态代理类 * @author 张薄- huaxiangniaoyu0109@126.com * @date 2015年5月26日 下午8:34:21 */public class DynamicProxy implements InvocationHandler {private Object obj; //委托类//具体指示引入了类,但是并没有指定具体的委托类是哪一个,在运行的时候才动态装载进去public DynamicProxy(Object obj) { this.obj = obj ;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("obj : " + obj.getClass().getName());System.out.println("proxy : " + proxy.getClass().getName());System.out.println("method : " + method.getName());System.out.println("args : " + args);//获取委托类的所有方法和参数Object result = method.invoke(this.obj, args);return result;}}
package DynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;/** * @ClassName: Client * @Description: 在客户端去配置代理类用哪个委托类,具体再用到哪一个方法,延迟加载。实现动态灵活可配。 * @author 张薄- huaxiangniaoyu0109@126.com * @date 2015年5月26日 下午8:39:45 */public class Client {public static void main(String[] args){//声明和实例化委托类Subject realSubject = new RealSubject();//获取委托类的类加载器,以便在虚拟机上运行加载字节码ClassLoader loader = realSubject.getClass().getClassLoader();//获取委托类的所有接口类,以便实现接口类的所有方法Class<?>[] interfaces = realSubject.getClass().getInterfaces(); //实例化代理类InvocationHandler handler = new DynamicProxy(realSubject); //动态的将选中的委托类加载到代理类中,实现灵活可配,动态加载Subject dynamicProxy =(Subject)Proxy.newProxyInstance(loader, interfaces, handler);//执行代理方法dynamicProxy.giveGift();}}
四、思考:动态代理?AOP?
- 代理模式--静态代理和动态代理
- 设计模式- 代理模式 (静态代理 和 动态代理)
- 代理模式(静态代理和动态代理)
- Spring的代理模式(静态代理和动态代理)
- Spring的代理模式(静态代理和动态代理)
- java的代理模式(动态代理和静态代理)
- 代理模式(静态代理和动态代理) JAVA
- 静态代理模式和动态代理模式
- 设计模式之代理模式(静态代理、JDK动态代理和cglib动态代理)
- 设计模式之代理模式--静态代理和动态代理
- Java中的代理模式----静态代理和动态代理
- 代理模式 静态代理和动态代理的区别
- java代理模式--静态代理和动态代理
- java 代理模式 静态代理和动态代理
- java的代理模式(静态和动态代理)
- 静态代理和动态模式
- 代理模式、静态代理、动态代理、aop
- Java代理模式 静态代理 动态代理
- hdu 1114 Piggy-Bank(完全背包)
- 玩转Light Blue之添加设备信息
- android利用线程池高效实现异步任务
- Hibernate的事务管理
- Mat 与 Iplimage之间的转换
- 代理模式(静态代理和动态代理)
- 基数排序
- Linux 内核定时器及使用方法
- 黑马程序员---IO流的一些总结
- 线程池的生命周期和拒绝策略
- 网页版百度地图--根据城市名定位
- hdu 1284 钱币兑换问题(完全背包 母函数)
- 用Switch控制视图的淡入淡出效果
- 百度地图--根据经纬度定位