深入研究jvm,动态代理
2010-02-24 10:13
225 查看
Java
程序的工作机制:
Java
对象都以单独的
class
文件存在,
java
虚拟机将其载入并执行其虚拟机指令。
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
。
Java
虚拟机加载这些
java
对象:
每个
java
虚拟机都在其启动时产生一个唯一的
class heap
,并把所有的
class instance
都分配在其中。其中每个类实例的信息又分两部分,
fields
域和
methods
域。每个类实例各自拥有
fields
,但同一个类的不同实例共享
methods
反射
JVM
对反射的处理
简单例子代码:
复杂例子代码:
分析:
java
虚拟机把每个
methods
当作一个执行单元。该执行单元带有两种签名:类签名和属性签名(
public
,
static
等)。
反射的第一步,验证签名的合法性。验证通过后,顺序执行该
method
中的指令,当需要访问类实例的
fields
和传入参数时,由虚拟机注入。
动态代理
Sun
对动态代理的说明:
一个简单例子代码:
动态代理的内部实现——代码生成:
研究
JDK
源代码,发现在
Proxy
的
sun
实现中调用了
sun.misc.ProxyGenerator
类的
generateProxyClass( proxyName, interfaces)
方法,其返回值为
byte[]
和
class
文件的内存类型一致。于是做如下试验:
运行该类,到
class
文件夹下,利用反编译技术,发现原来其采用了代码生产技术:
程序的工作机制:
Java
对象都以单独的
class
文件存在,
java
虚拟机将其载入并执行其虚拟机指令。
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
。
Java
虚拟机加载这些
java
对象:
每个
java
虚拟机都在其启动时产生一个唯一的
class heap
,并把所有的
class instance
都分配在其中。其中每个类实例的信息又分两部分,
fields
域和
methods
域。每个类实例各自拥有
fields
,但同一个类的不同实例共享
methods
反射
JVM
对反射的处理
简单例子代码:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; import java.io.IOException; public class Main { 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; public class Main { 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. } } } |
java
虚拟机把每个
methods
当作一个执行单元。该执行单元带有两种签名:类签名和属性签名(
public
,
static
等)。
反射的第一步,验证签名的合法性。验证通过后,顺序执行该
method
中的指令,当需要访问类实例的
fields
和传入参数时,由虚拟机注入。
动态代理
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
文件夹下,利用反编译技术,发现原来其采用了代码生产技术:
public interface Temp{ public void Talk(); public void Run(); } |
import java.lang.reflect.*; public final class TempProxy extends Proxy implements Temp{ private static Method m4; private static Method m2; private static Method m0; private static Method m3; private static Method m1; public TempProxy(InvocationHandler invocationhandler) { super(invocationhandler); } public final void Run() { try { h.invoke(this, m4, null); return; } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String toString(){ try{ return (String)h.invoke(this, m2, null); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return ""; } public final int hashCode() { try { return ((Integer)h.invoke(this, m0, null)).intValue(); } catch(Error _ex) { } catch(Throwable throwable){ throw new UndeclaredThrowableException(throwable); } return 123; } public final void Talk(){ try{ h.invoke(this, m3, null); return; } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final boolean equals(Object obj) { try { return ((Boolean)h.invoke(this, m1, new Object[] { obj })).booleanValue(); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } return false; } static{ try{ m4 = Class.forName("Temp").getMethod("Run", new Class[0]); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m3 = Class.forName("Temp").getMethod("Talk", new Class[0]); m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); } catch(NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch(ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } } |
相关文章推荐
- 【Java深入研究】5、Proxy动态代理机制详解
- 深入研究java中的静态代理和动态代理
- 【Java深入研究】6、CGLib动态代理机制详解
- 初识动态代理(值得深入研究的知识点)
- 深入理解java动态代理机制
- 深入理解Cglib动态代理及手动实现
- Java 动态代理深入解析
- Java虚拟机的深入研究(内存管理---垃圾回收---JVM调优)
- Java 动态代理深入解析
- 关于动态代理的研究
- 深入剖析JDK动态代理实现原理
- Java 动态代理深入解析
- JDK动态代理与Dubbo自实现动态代理的研究
- 深入理解JVM之七:静态分派与动态分派
- 深入Java机制(一)--反射机制和动态代理机制
- java 代理模式及动态代理机制深入分析
- Java动态代理深入解析
- Java动态代理深入解析
- AOP技术应用和研究--动态代理
- 深入理解JVM之七:静态分派与动态分派