求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
设计模式:代理模式和反射原理
 

作者:xiaokui008,发布于2012-3-16

 

代理模式:为其他对象提供一种代理以控制对这个对象的访问。

Proxy和RealSubject类共同实现了Subject接口,这样一来,在任何地方使用RealSubject类的地方就可以使用Proxy类来代理。而在真正操作前可以对其进行一些其他操作。

静态代理:

静态代理即Proxy类为静态的,不能再程序加在到内存时动态的创建。看一下静态代理的时序图。

如果RealSubject这种类有许多,对应的Proxy类就会有很多。这样就出现了一个问题,即代理类过多,重复代码过多。动态代理则克服了这种困难。

动态代理:

动态代理的意思即Proxy类是在程序加载到内存中动态的创建。

在JAVA中,代理类实现了反射中的InvocationHandler接口和Proxy,Method类即可实现动态代理。

动态代理的过程:

1.利用Proxy类反射机制创建出目标类。

2.将实现了InvocationHandler接口的类放到动态创建的代理类中

3.调用InvocationHandler接口的类的invoke方法和Method类。在这里Method是作为invoke方法的一个参数出现的。

4.在invoke方法中去调用实际要做的事情。

看一下时序图:

PS:Jdk代理类我们是看不到的,这个类是通过Proxy类通过反射实例化来的,在实例化过程中,会New一个LogHandler类当成代理类中的一个参数。所以能调用LogHandler类中的invoke方法。

在动态代理类中的代码:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

public class LogHandler implements InvocationHandler {

privateObject targetObject;

//创建目标类,参数为Object

public Object newProxyInstance(Object targetObject) {

this.targetObject = targetObject;

//getClassLoader为目标类的装载器

//getInterfaces为目标类的接口

//this为InvocationHandler类型对象

//在代理类中调用具体类方法时,调用的是InvocationHandler对象的invoke方法

//在内存中创建代理类的时候把LogHandler放到了代理类中

//在此处只需传过来要创建的对象即可创建相应的目标类

return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),

                            targetObject.getClass().getInterfaces(), this);

}

public Object invoke(Object proxy, Method method, Object[] args)

        throws Throwable {

Object ret = null;

try {

        //调用目标方法

        // targetObject目标类

        ret = method.invoke(targetObject, args);

}catch(Exception e) {

        e.printStackTrace();

        throw e;

}

return ret;

}

}

在这里把创建目标类写到了LogHandler类中,在实际开发中,这个方法可以单独的写到一个类中,在创建目标类的时候不要忘记new一个LogHandler放到其中即可。在代理中,用到了反射,下面是简单的反射原理。

反射原理:

在理解反射的时候,不得不说一下内存。

先理解一下JVM的三个区:堆区,栈区,和方法去(静态区)。

堆区:存放所有的对象,每个对象都有一个与其对应的class信息。在JVM中只有一个堆区,堆区被所有的线程共享。

栈区:存放所有基础数据类型的对象和所有自定义对象的引用,每个线程包含一个栈区。每个栈区中的数据都是私有的,其他栈不能访问。

栈分为三部分:

基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

方法区:即静态区,被所有的线程共享。方法区包含所有的class和static变量。它们都是唯一的。

在启动一个java虚拟机时,虚拟机要加载你程序里所用到的类 ,这个进程会首先跑到jdk中(在jdk的jre/lib/ext文件夹里找那些jar文件),如果没有找到,会去classpath里设置的路径去找。

在找到要执行的类时:

1.首先将找到的类的信息加载到运行时数据区的方法区。这个过程叫做类的加载。所以一下static类型的在类的加载过程中就已经放到了方法区。所以不用实例化就能用一个static类型的方法。

2.加载完成后,在new一个类时,首先就是去方法区看看有没有这个类的信息。如果没有这个类的信息,先装载这个类。then,加载完成后,会在堆区为new的这个类分配内存,有了内存就有了实例,而这个实例指向的是方法区的该类信息。其实就是存放了在方法区的地址。而反射就是利用了这一点。

下面是new一个类在内存中的动态。

通过方法区的类型信息就可以反射出一个test实例来。即反射。


相关文章

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

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

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


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

相关培训课程

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


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