透过字节码分析Java动态代理机制。

一、创建动态代理代码

1、创建接口

public interface Subject {
    void request();
}

  

2、创建接口实现类

public class RealSubject  implements  Subject
{
    @Override
    public void request() {
        System.out.println("From real subject");
    }
}

  

3、创建DynamicSubject类

public class DynamicSubject implements InvocationHandler {

    private  Object sub;

    public  DynamicSubject(Object obj){
        this.sub = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before calling:" + method);
        method.invoke(this.sub, args);
        System.out.println("after calling:" + method);
        return null;
    }
}

  

4、创建测试类

public class Client {
    public static void main(String[] args) {

        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

        RealSubject rs = new RealSubject();
        InvocationHandler ds = new DynamicSubject(rs);

        Class<?> cls = rs.getClass();
        Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ds);
        subject.request();

        System.out.println(subject.getClass());
        System.out.println(subject.getClass().getSuperclass());
    }
}

  输出结果:

before calling:public abstract void com.example.jvm.bytecode.Subject.request()
From real subject
after calling:public abstract void com.example.jvm.bytecode.Subject.request()
class com.sun.proxy.$Proxy0
class java.lang.reflect.Proxy

  

查看源码,动态代理类在ProxyGenerator类的generateProxyClass生成。

   public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        final byte[] var4 = var3.generateClassFile();
        if(saveGeneratedFiles) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    try {
                        int var1 = var0.lastIndexOf(46);
                        Path var2;
                        if(var1 > 0) {
                            Path var3 = Paths.get(var0.substring(0, var1).replace(‘.‘, File.separatorChar), new String[0]);
                            Files.createDirectories(var3, new FileAttribute[0]);
                            var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                        } else {
                            var2 = Paths.get(var0 + ".class", new String[0]);
                        }

                        Files.write(var2, var4, new OpenOption[0]);
                        return null;
                    } catch (IOException var4x) {
                        throw new InternalError("I/O exception saving generated file: " + var4x);
                    }
                }
            });
        }

        return var4;
    }

  可以发现saveGeneratedFiles为true时,可以将代理类保存到磁盘上。

因此在测试类中sun.misc.ProxyGenerator.saveGeneratedFiles属性设置为true

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

最终生成的.class 文件位置如下图



原文地址:https://www.cnblogs.com/linlf03/p/11109977.html

时间: 2024-10-14 02:03:59

透过字节码分析Java动态代理机制。的相关文章

透过字节码分析java基本类型数组的内存分配方式。

我们知道java中new方式创建的对象都是在堆中创建的,而局部变量对应的值存放在栈上.那么java中的int [] arr={1,2,3}是存放在什么地方的呢,int []arr = new int[3]又是存放在什么地方的呢, 下面我们通过编写两个小例子,通过查看生成的字节码文件,来了解jvm会如何来处理这两种情况的. 1.int[] arr = new int[3]示例 public class ArrayTest { public static void main(String[] arg

Java 动态代理机制分析及扩展,第 1 部分

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 回页首 代理:设计模式 代理是一种常用的设计

Java 动态代理机制分析及扩展

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理:设计模式 代理是一种常用的设计模式,其

[转]Java 动态代理机制分析及扩展

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现. 代理:设计模式 代理是一种常用的设计模式,其

字节码技术及动态代理

.output_wrapper pre code { font-family: Consolas, Inconsolata, Courier, monospace; display: block !important; white-space: pre !important; overflow: auto !important } .task-list-list { list-style-type: none } .task-list-list.checked { color: rgb(62,

java动态代理机制

首先了解代理设计模式,其思想是为其他对象提供一种代理以控制对这个对象的访问. java动态代理就是遵循这种思想,spring中的AOP实现原理就是java的动态代理. 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的. 每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通

好程序员Java教程Java动态代理机制详解

好程序员Java教程Java动态代理机制详解:在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的.首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的: InvocationHandler: 1InvocationHandler is the interface implemented by the invocation handle

Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

作者:亦山 推荐:hh375的图书馆 class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象: class字节码文件是根据JVM虚拟机规范中规定的字节码组织规则生成的.具体class文件是怎样组织类信息的,可以参考 此博文:深入理解Java Class文件格式系列.或者

Java 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象: class字节码文件是根据JVM虚拟机规范中规定的字节码组织规则生成的.具体class文件是怎样组织类信息的,可以参考 此博文:深入理解Java Class文件格式系列.或者是Java虚拟机规范. 下面通过一段代