- 浏览: 139478 次
- 性别:
- 来自: 福州
最新评论
-
semmy:
牛人,我的偶像
关于架构的思考 -
mercyblitz:
引用1. SPI和API存在业务不匹配问题。虽然组件A依赖组件 ...
企业应用下的业务组件开发实践 -
凤舞凰扬:
楼上初步总结了一些,我本来有想法打算写一个架构师之路系列 ...
浅谈企业应用架构(一) -
lgch123:
做伟大的事业,不是说说就能起来的。
浅谈企业应用架构(一) -
hanyou:
写的非常好,如果你是原版,那么你肯定从事了多年的开发,有丰富的 ...
浅谈企业应用架构(一)
<!----> <o:p>(从csdn的blog转来) </o:p>
Java 程序的工作机制: Java 对象都以单独的 class 文件存在, java 虚拟机将其载入并执行其虚拟机指令。
<o:p> </o:p>
Java 虚拟机查找这些 java 对象:
java 虚拟机根据 class path 来查找 java 对象,而虚拟机的 class path 又分为三层:
bootstrap : sun.boot.class.path
extension: java.ext.dirs
application: java.class.path
三个 class path 各有对应的 classloader 。由上而下形成父子关系
当程序中调用 new 指令,或者 ClassLoader.load 方法时。其顺序如下:
1. 首先查看 application 的 classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。
2. 首先查看 extension 的 classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。
3. 首先查看 bootstrap 的 classloader 中是否已有对应的 class 缓存,如果有则返回,并根据 class 分配内存。如果没有,接下一步。
4. 由 bootstrap 的 classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,接下一步。
5. 由 extension 的 classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,接下一步。
6. 由 application 的 classloader 在其 class path 中试图加载该 class ,如果有,则将该 class 放入 cache 中,并返回。如果没有,则抛出 ClassNotFound 的 exception 。
<o:p> </o:p>
Java 虚拟机加载这些 java 对象:
每个 java 虚拟机都在其启动时产生一个唯一的 class heap ,并把所有的 class instance 都分配在其中。其中每个类实例的信息又分两部分, fields 域和 methods 域。每个类实例各自拥有 fields ,但同一个类的不同实例共享 methods
<o:p> </o:p>
反射
JVM 对反射的处理
简单例子代码:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.io.IOException; <o:p> </o:p> public class <!----><st1:place w:st="on">Main</st1:place> { public static void main(String[] args){ TempImpl t1 = new TempImpl("temp1"); try { Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ; t1Talk.invoke(t1, null); } catch (NoSuchMethodException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IllegalAccessException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } try { System.in.read(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } |
复杂例子代码:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.io.IOException; <o:p> </o:p> public class <st1:place w:st="on">Main</st1:place> { public static void main(String[] args){ TempImpl t1 = new TempImpl("temp1"); TempImpl t2 = new TempImpl("temp2"); Temp2 temp2 = new Temp2(); try { Method t1Talk = t1.getClass().getMethod("Talk", new Class[0]) ; Method t2Talk = t2.getClass().getMethod("Talk", new Class[0]) ; t1Talk.invoke(t2, null); t2Talk.invoke(t1, null); if(t1Talk.equals(t2Talk)){ System.out.println("equals"); } else{ System.out.println("not equals"); } if(t1Talk==t2Talk){ System.out.println("ref equals"); } else{ System.out.println("ref not equals"); } t2Talk.invoke(temp2, null); } catch (NoSuchMethodException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IllegalAccessException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (InvocationTargetException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } try { System.in.read(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } |
<o:p> </o:p>
分析: java 虚拟机把每个 methods 当作一个执行单元。该执行单元带有两种签名:类签名和属性签名( public , static 等)。 反射的第一步,验证签名的合法性。验证通过后,顺序执行该 method 中的指令,当需要访问类实例的 fields 和传入参数时,由虚拟机注入。
<o:p> </o:p>
动态代理
Sun 对动态代理的说明:
一个简单例子代码:
动态代理的内部实现——代码生成:
研究 JDK 源代码,发现在 Proxy 的 sun 实现中调用了 sun.misc.ProxyGenerator 类的 generateProxyClass( proxyName, interfaces) 方法,其返回值为 byte[] 和 class 文件的内存类型一致。于是做如下试验:
public class ProxyClassFile{ public static void main(String[] args){ String proxyName = "TempProxy"; TempImpl t = new TempImpl("proxy"); Class[] interfaces =t.getClass().getInterfaces();
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces); File f = new File("classes/TempProxy.class"); try { FileOutputStream fos = new FileOutputStream(f); fos.write(proxyClassFile); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } } |
运行该类,到 class 文件夹下,利用反编译技术,发现原来其采用了代码生产技术:
<o:p> </o:p>
public interface Temp{<o:p></o:p> public void Talk();<o:p></o:p> public void Run();<o:p></o:p> }<o:p></o:p> |
import java.lang.reflect.*;<o:p></o:p> <o:p> </o:p> public final class TempProxy extends Proxy<o:p></o:p> implements Temp{<o:p></o:p> <o:p> </o:p> private static Method m4;<o:p></o:p> private static Method m2;<o:p></o:p> private static Method m0;<o:p></o:p> private static Method m3;<o:p></o:p> private static Method m1;<o:p></o:p> <o:p> </o:p> public TempProxy(InvocationHandler invocationhandler) {<o:p></o:p> super(invocationhandler);<o:p></o:p> }<o:p></o:p> <o:p> </o:p> public final void Run() {<o:p></o:p> try {<o:p></o:p> h.invoke(this, m4, null);<o:p></o:p> return;<o:p></o:p> }<o:p></o:p> catch(Error _ex) { }<o:p></o:p> catch(Throwable throwable) {<o:p></o:p> throw new UndeclaredThrowableException(throwable);<o:p></o:p> }<o:p></o:p> }<o:p></o:p> <o:p> </o:p> public final String toString(){<o:p></o:p> try{<o:p></o:p> return (String)h.invoke(this, m2, null);<o:p></o:p> }<o:p></o:p> catch(Error _ex) { }<o:p></o:p> catch(Throwable throwable) {<o:p></o:p> throw new UndeclaredThrowableException(throwable);<o:p></o:p> }<o:p></o:p> return "";<o:p></o:p> }<o:p></o:p> <o:p> </o:p> public final int hashCode() {<o:p></o:p> try {<o:p></o:p> return ((Integer)h.invoke(this, m0, null)).intValue();<o:p></o:p> }<o:p></o:p> catch(Error _ex) { }<o:p></o:p> catch(Throwable throwable){<o:p></o:p> throw new UndeclaredThrowableException(throwable);<o:p></o:p> }<o:p></o:p> return 123;<o:p></o:p> }<o:p></o:p> <o:p> </o:p> public final void Talk(){<o:p></o:p> try{<o:p></o:p> h.invoke(this, m3, null);<o:p></o:p> return;<o:p></o:p> }<o:p></o:p> catch(Error _ex) { }<o:p></o:p> catch(Throwable throwable) {<o:p></o:p> throw new UndeclaredThrowableException(throwable);<o:p></o:p> }<o:p></o:p> }<o:p></o:p> <o:p> </o:p> public final boolean equals(Object obj) {<o:p></o:p> try {<o:p></o:p> return ((Boolean)h.invoke(this, m1, new Object[] {<o:p></o:p> obj<o:p></o:p> })).booleanValue();<o:p></o:p> }<o:p></o:p> catch(Error _ex) { }<o:p></o:p> catch(Throwable throwable) {<o:p></o:p> throw new UndeclaredThrowableException(throwable);<o:p></o:p> }<o:p></o:p> return false;<o:p></o:p> }<o:p></o:p> <o:p> </o:p> static{<o:p></o:p> try{<o:p></o:p> m4 = Class.forName("Temp").getMethod("Run", new Class[0]);<o:p></o:p> m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);<o:p></o:p> m0 = Class.forName("java.lang.Object").getMethod("hashCode", ne |
发表评论
-
从EAI到SOA
2007-08-18 14:42 1946(2008-1-12更新) 写在前面SOA现在越发闹腾的厉害 ... -
Web框架比较
2007-05-23 23:06 3550Blog好久没有更新了, 最近一直忙于一个新项目,在这个项 ... -
编译器的春天
2007-04-11 23:24 4579为什么这么说呢?这样说是有理由的: 先来看看Java世界中看看 ... -
Template和JSP技术
2006-06-11 14:36 6059(从csdn的blog上同步过来)(本文发于java emag ... -
单元测试实践小结
2006-06-12 23:30 1603在系统开发过程种使用单元测试,会带来很多的的好处,最明显为: ... -
写在Tapestry 升级成为Apache一级项目之时
2006-07-01 17:00 1518是的,我内心很喜欢Tapestry。我喜欢他的开发风格,这和我 ... -
项目闹鬼之hibernate2.1.6
2006-07-28 11:00 1379项目用的持久化层是hibernate 2.1.6.前不久出现一 ... -
NEWS: Microsoft DSL Tools 1.0 RTM
2006-09-21 18:24 904NEWS: Microsoft DSL Tools 1.0 R ...
相关推荐
本主题将深入探讨JVM技术,特别是反射与动态代理这两个关键特性。 一、JVM技术 1. 类加载机制:JVM通过类加载器(ClassLoader)来加载.class文件,分为启动类加载器、扩展类加载器和应用程序类加载器。类的加载...
在Java编程语言中,反射、动态代理和注解是三个重要的高级特性,它们极大地扩展了Java的灵活性和可扩展性。下面将详细讲解这三个概念及其应用。 **反射(Reflection)** 反射是Java提供的一种能力,允许程序在运行时...
Java的反射机制与动态代理是Java编程中两个非常重要的高级特性,它们在实际开发中有着广泛的应用。反射机制允许程序在运行时动态地获取类的信息并操作类的对象,而动态代理则提供了一种创建和控制代理对象的方式,...
在"Java深度历险(七)——Java反射与动态代理"中,我们探讨了如何利用反射API获取类的运行时信息以及如何动态地执行类的操作。 首先,反射API的核心是`java.lang.Class`类,它代表了Java程序中的每一个类型。通过`...
Java反射与动态代理是Java语言中的高级特性,它们允许程序在运行时检查和操作类、对象及它们的成员。在本文中,我们将深入探讨这两个概念,了解如何使用反射API进行类的动态操作,并掌握动态代理的基本用法及其在AOP...
动态代理是反射的一部分,通过`Proxy.newProxyInstance()`方法可以创建一个代理对象,该对象可以拦截调用并执行自定义逻辑。代理对象可以用来处理如缓存、事务管理、日志记录等跨切面的职责。 最后,`Annotation`...
总的来说,Java反射和动态代理提供了一种强大的工具,允许我们在运行时探索和操作类的结构,实现代码的动态扩展和灵活控制。这对于构建可扩展、可维护的系统至关重要,尤其是在需要实现复杂逻辑如日志记录、性能监控...
四、静态代理与动态代理的比较 1. **灵活性**:动态代理比静态代理更灵活,因为不需要预先编写代理类的源代码,可以适应接口的变化。 2. **代码量**:静态代理需要为每个委托类编写单独的代理类,如果委托类很多,会...
在Android开发中,反射、注解和动态代理是三个非常重要的高级特性,它们极大地提高了代码的灵活性和可维护性。接下来我们将深入探讨这三个概念以及它们的综合应用。 反射(Reflection)是Java提供的一种机制,允许...
本文档涵盖了JavaSE中高级反射和JVM相关的知识点,包括Java中的反射机制、动态代理、设计模式、回收机制、JDK7和JDK8的区别、Jvm虚拟机原理等。 一、 Java中的反射机制 Java中的反射机制是指可以在运行时inspect和...
通过分析这些class文件,我们可以更深入地理解Java虚拟机(JVM)是如何执行动态代理的。同时,这两个项目也为我们提供了一个实践和调试动态代理的平台,有助于提升我们的编程技能和对Java底层机制的理解。