- 浏览: 137172 次
- 性别:
- 来自: 福州
最新评论
-
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 3504Blog好久没有更新了, 最近一直忙于一个新项目,在这个项 ... -
编译器的春天
2007-04-11 23:24 4490为什么这么说呢?这样说是有理由的: 先来看看Java世界中看看 ... -
Template和JSP技术
2006-06-11 14:36 6012(从csdn的blog上同步过来)(本文发于java emag ... -
单元测试实践小结
2006-06-12 23:30 1554在系统开发过程种使用单元测试,会带来很多的的好处,最明显为: ... -
写在Tapestry 升级成为Apache一级项目之时
2006-07-01 17:00 1471是的,我内心很喜欢Tapestry。我喜欢他的开发风格,这和我 ... -
项目闹鬼之hibernate2.1.6
2006-07-28 11:00 1329项目用的持久化层是hibernate 2.1.6.前不久出现一 ... -
NEWS: Microsoft DSL Tools 1.0 RTM
2006-09-21 18:24 904NEWS: Microsoft DSL Tools 1.0 R ...
相关推荐
Java程序的工作机制:Java对象都以单独的class文件存在,java虚拟机将其载入并执行其虚拟机指令。
reflection是一系列的API,用于表示或者处理当前JVM中的类,接口和对象. java.lang.reflect/java.lang.Class 在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
调用对象的方法,与直接在源代码中的交互是一样的,但又提供了额外的在运行时候的灵活性,但反射的一个最大的弊端就是性能比较差,相同的操作,用反射API所需的时间大概比直接使用慢一两个数量级,不过现在的JVM实现...
javaStrengthenJava 高级特性增强。包括多线程增强、Java并发包、Java JMS技术、Java JVM技术、Java动态代理以及反射。
简介一些Java程序使用反射通过动态加载和执行类来隐藏其代码。 您可以从内存中转储它们,但是如果它们在执行后立即被卸载怎么办? 您可以编辑rt.jar并将钩子放在各种反射方法上。 但是,如果程序直接使用本机类加载...
文章目录一、Java反射定义二、Java反射机制实现1、Class对象获取2、获取class对象的摘要信息3、获取class对象的属性、方法、构造函数等三、反射的应用场景1、动态代理2、自定义注解实现日志管理 写在前面:Java反射...
动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。 - **优点:** 运行期类型的判断,动态加载类,提高代码灵活度。 - **缺点:** 性能瓶颈:反射相当于一...
Proxy动态代理机制详解 从整体上观察对象 网络开发 Servlet基础,生命周期执行过程 Http请求详解,握手挥手流程简介 会话跟踪技术,Session和Cookie详解 过滤器、监听器、拦截器,应用详解 Servlet 集成 C3P0
1、掌握多线程 2、掌握并发包下的队列 3、了解JMS 4、掌握JVM技术 5、掌握反射和动态代理
它比使用java反射的JDK动态代理要快。 CGLIB底层:使用字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。 CGLIB缺点:对于...
java的高级特性总结,多线程的各种实现,jvm技术,以及动态代理和反射的理解
包括JavaSE基础(多态、异常处理、常用API、数据类型、IO操作、集合、多线程和并发库、内部类)、JavaSE高级(反射、动态代理、设计模式&回收机制、加载器、JVM基础、GC基础)、JavaWeb基础(JDBC技术、HTTP协议、...
本书是Java技术经典参考书,多年畅销不衰,第7版在保留以前版本风格的基础上,涵盖Java 2开发平台标准版J2SE 5.0的基础知识,主要内容包括面向对象程序设计、反射与代理、接口与内部类、事件监听器模型、使用Swing ...
Spring 4.x ...动态代理:在程序运行期间由JVM根据反射机制动态生成的,不存在代理类的字节码文件,代理对象和目标对象的关系是在程序运行时决定的。 动态代理两种方式 JDK代理:要求目标对象必须有接口
动态代理 JDK8新特性 集合容器 多线程与并发 Spring SpringMVC SpringBoot Mybatis 数据结构与算法 入门基础 基础数据结构 数组&链表 数组&链表进阶 栈 队列 算法思想 数论&枚举&递归&分治&回溯 排序及其源码实现 ...
ORM,动态SQL、动态代理 第十篇:Spring 那点破事!IOC、AOP、生命周期、动态代理、设计模式 第十一篇:Spring Boot !starter组件、JPA、定时任务、全局异常 第十二篇:Spring Cloud !Gateway、注册发现、Hystrix...
揭开springAOP神秘面纱(动态代理) Mysql性能优化之索引优化 写实现Tomcat服务器 移动后台端框架设计 公司级框架原理解析 解密公司内部框架开发(打造属于自己的专属框架) 手写Tomca之深度解析动态资源请求原理 深度...
反射机制;多线程;IO/NIO; 网络编程;常用数据结构和相关算法。 2、对面向对象的软件开发思想有清晰的认识、熟悉掌握常用的设计模式;设计模式;单例模式;工厂模式;代理模式;模板方法模式;责任链模式等。 3...
【对线面试官】Java反射 && 动态代理 爪哇 【对线面试官】多线程基础 【对线面试官】 CAS 【对线面试官】同步进行 【对线面试官】AQS&&ReentrantLock 【对线面试官】线程池 【对线面试官】ThreadLocal 【对线面试官...
1.3.2 Java程序的运行机制和JVM 6 1.4 开发Java的准备 7 1.4.1 安装JDK 8 学生提问:不是说JVM是运行Java程序的虚拟机吗?那JRE和JVM的关系是怎样的呢? 8 学生提问:为什么不安装公共JRE系统呢? 9 1.4.2 设置...