`
wj0573
  • 浏览: 8732 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java ASM、Cglib、aop

    博客分类:
  • java
 
阅读更多

ASM

我们知道Java是静态语言,而pythonruby是动态语言Java程序一旦写好很难在运行时更改类的行为,而pythonruby可以;不过java可以通过MagicASM等一些开源库去动态生成字节码文件;

 

它是一个Java字节码修改框架,能直接生成二进制类代码或者动态修改类代码,生成stub类或者其他类似代理类。ASM要比BCEL和SERP小的多,其核心部分才33KB,速度也要比这些工具快的多,大概要比BCEL快7倍,比SERP快11倍。由于ASM设计的目的就是在运行时使用,因此它的体积尽可能小,速度尽可能快;可以用于动态生成stub类和其他代理类,截获类调用,添加一些横向功能。采用这种接口,你可以简单的实现面向方面的功能,比如添加安全、事务、日志、过滤、编码、解码等等的功能,而且是纯粹热插拔的模式。总之使用动态代理能够实现许多AOP方面的功能;

 

代码参考:

 

Java代码

  1. import java.io.FileOutputStream;   
  2. import java.io.PrintStream;   
  3.   
  4. import org.objectweb.asm.ClassWriter;   
  5. import org.objectweb.asm.MethodVisitor;   
  6. import org.objectweb.asm.Opcodes;   
  7. import org.objectweb.asm.Type;   
  8. import org.objectweb.asm.commons.GeneratorAdapter;   
  9. import org.objectweb.asm.commons.Method;   
  10.   
  11. public class Helloworld extends ClassLoader implements Opcodes {   
  12.   
  13.   public static void main(final String args[]) throws Exception {   
  14.   
  15.     // creates a ClassWriter for the Example public class,   
  16.     // which inherits from Object   
  17.   
  18.      ClassWriter cw = new ClassWriter(0);   
  19.      cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);   
  20.      MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,   
  21.         null);   
  22.      mw.visitVarInsn(ALOAD, 0);   
  23.      mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");   
  24.      mw.visitInsn(RETURN);   
  25.      mw.visitMaxs(1, 1);   
  26.      mw.visitEnd();   
  27.      mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",   
  28.         "([Ljava/lang/String;)V", null, null);   
  29.      mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",   
  30.         "Ljava/io/PrintStream;");   
  31.      mw.visitLdcInsn("Hello world!");   
  32.      mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",   
  33.         "(Ljava/lang/String;)V");   
  34.      mw.visitInsn(RETURN);   
  35.      mw.visitMaxs(2, 2);   
  36.      mw.visitEnd();   
  37.     byte[] code = cw.toByteArray();   
  38.      FileOutputStream fos = new FileOutputStream("Example.class");   
  39.      fos.write(code);   
  40.      fos.close();   
  41.      Helloworld loader = new Helloworld();   
  42.      Class exampleClass = loader   
  43.          .defineClass("Example", code, 0, code.length);   
  44.      exampleClass.getMethods()[0].invoke(null, new Object[] { null });   
  45.   
  46.     // ------------------------------------------------------------------------   
  47.     // Same example with a GeneratorAdapter (more convenient but slower)   
  48.     // ------------------------------------------------------------------------   
  49.   
  50.      cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);   
  51.      cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);   
  52.      Method m = Method.getMethod("void <init> ()");   
  53.      GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,   
  54.          cw);   
  55.      mg.loadThis();   
  56.      mg.invokeConstructor(Type.getType(Object.class), m);   
  57.      mg.returnValue();   
  58.      mg.endMethod();   
  59.      m = Method.getMethod("void main (String[])");   
  60.      mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);   
  61.      mg.getStatic(Type.getType(System.class), "out", Type   
  62.          .getType(PrintStream.class));   
  63.      mg.push("Hello world!");   
  64.      mg.invokeVirtual(Type.getType(PrintStream.class), Method   
  65.          .getMethod("void println (String)"));   
  66.      mg.returnValue();   
  67.      mg.endMethod();   
  68.      cw.visitEnd();   
  69.      code = cw.toByteArray();   
  70.      loader = new Helloworld();   
  71.      exampleClass = loader.defineClass("Example", code, 0, code.length);   
  72.      exampleClass.getMethods()[0].invoke(null, new Object[] { null });   
  73.    }   
  74. }  

import java.io.FileOutputStream;

import java.io.PrintStream;

 

import org.objectweb.asm.ClassWriter;

import org.objectweb.asm.MethodVisitor;

import org.objectweb.asm.Opcodes;

import org.objectweb.asm.Type;

import org.objectweb.asm.commons.GeneratorAdapter;

import org.objectweb.asm.commons.Method;

 

public class Helloworld extends ClassLoader implements Opcodes {

 

  public static void main(final String args[]) throws Exception {

 

    // creates a ClassWriter for the Example public class,

    // which inherits from Object

 

    ClassWriter cw = new ClassWriter(0);

    cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

    MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,

        null);

    mw.visitVarInsn(ALOAD, 0);

    mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");

    mw.visitInsn(RETURN);

    mw.visitMaxs(1, 1);

    mw.visitEnd();

    mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",

        "([Ljava/lang/String;)V", null, null);

    mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",

        "Ljava/io/PrintStream;");

    mw.visitLdcInsn("Hello world!");

    mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",

        "(Ljava/lang/String;)V");

    mw.visitInsn(RETURN);

    mw.visitMaxs(2, 2);

    mw.visitEnd();

    byte[] code = cw.toByteArray();

    FileOutputStream fos = new FileOutputStream("Example.class");

    fos.write(code);

    fos.close();

    Helloworld loader = new Helloworld();

    Class exampleClass = loader

        .defineClass("Example", code, 0, code.length);

    exampleClass.getMethods()[0].invoke(null, new Object[] { null });

 

    // ------------------------------------------------------------------------

    // Same example with a GeneratorAdapter (more convenient but slower)

    // ------------------------------------------------------------------------

 

    cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

    cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);

    Method m = Method.getMethod("void <init> ()");

    GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,

        cw);

    mg.loadThis();

    mg.invokeConstructor(Type.getType(Object.class), m);

    mg.returnValue();

    mg.endMethod();

    m = Method.getMethod("void main (String[])");

    mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);

    mg.getStatic(Type.getType(System.class), "out", Type

        .getType(PrintStream.class));

    mg.push("Hello world!");

    mg.invokeVirtual(Type.getType(PrintStream.class), Method

        .getMethod("void println (String)"));

    mg.returnValue();

    mg.endMethod();

    cw.visitEnd();

    code = cw.toByteArray();

    loader = new Helloworld();

    exampleClass = loader.defineClass("Example", code, 0, code.length);

    exampleClass.getMethods()[0].invoke(null, new Object[] { null });

  }

}

上面的例子分别使用ASMMethodVisitorGeneratorAdapter两种方式来动态生成Example并调用打印语句。

分享到:
评论

相关推荐

    cglib和asm

    CGlib和ASM是Java开发中两个非常重要的库,主要用于字节码操作和动态代理。这两个库在Java生态系统中扮演着不可或缺的角色,特别是在AOP(面向切面编程)和ORM(对象关系映射)框架中。 CGlib是一个强大的、高性能...

    cglib aop spring 动态代理

    2.cglib封装了asm,可以在运行期动态生成新的class。 3.cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。 spring 的AOP功能中 会根据目标类是否实现了接口来判断使用 jdk Proxy还是cglib

    cglib.jar | asm.jar对应版本

    其中,`cglib.jar` 和 `asm.jar` 是实现Java动态代理的两个关键库,它们在许多框架和库中都有广泛的应用,比如Spring AOP和Hibernate。 `cglib.jar` 是一个强大的代码生成库,全称为Code Generation Library。它...

    asm + cglib demo

    ASM 和 CGlib 都是Java字节码操作框架,它们在Java编程中有着重要的应用,尤其是在动态代理、AOP(面向切面编程)等领域。ASM是一个底层的字节码操作库,而CGlib是基于ASM的更高层次的库,简化了对Java字节码的操作...

    cglib2.2.2.jar和asm3.3.1.jar

    总结来说,CGGLIB 2.2.2 和 ASM 3.3.1 是两个关键的Java开发工具,它们提供了字节码级别的操作能力,广泛应用于AOP框架、动态代理和类增强。了解并熟练使用这两个库,可以显著提升Java开发者的技能水平和解决问题的...

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

    在Java中,我们可以使用JDK自带的动态代理或者第三方库如CGLIB、Javassist、ASM来实现。 **JDK动态代理**: JDK的动态代理主要依赖于`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个类。...

    cglib-3.3.0.jar,asm-7.0.jar

    这里提到的"cglib-3.3.0.jar"和"asm-7.0.jar"是两个与Java动态代理密切相关的库。 首先,`cglib-3.3.0.jar`是Code Generation Library的简称,它是一个强大的高性能的代码生成库,广泛用于Java AOP(面向切面编程)...

    Cglib和asm的jar包

    Cglib和ASM是Java开发中的两个重要库,主要用于字节码操作和动态代理。这两个库在处理高性能、低级别的代码生成和优化时扮演着重要角色。以下是对这两个库的详细解释: **Cglib(Code Generation Library)** Cglib...

    java_cglib_lib.rar

    2. **asm.jar**:ASM是底层的Java字节码操作框架,CGlib在其基础上进行抽象和封装。ASM库提供了读取、修改和生成Java字节码的能力,它是CGlib实现动态代理的关键依赖。 3. **asm-commons.jar**:这是ASM的扩展库,...

    asm-cglib开发包

    ASM 和 CGLIB 是在Java开发中常用的两个库,它们主要与字节码操作和动态代理技术相关。这里我们将深入探讨这两个库的核心概念、功能以及它们在实际开发中的应用。 **ASM 库** ASM 是一个Java字节码操控和分析框架...

    SpringMVC3.0-Jar全量包含cglib几个包-aop的aspectj几个包

    这个压缩包包含了一系列与SpringMVC、AOP(面向切面编程)以及依赖库相关的JAR文件,如cglib、asm、aspectj等。下面将详细介绍这些关键组件及其在SpringMVC 3.0中的作用。 1. **SpringMVC**:Spring MVC是Spring...

    深入字节码 -- 使用 ASM 实现 AOP1

    与 Spring、AspectJ 和 CGLib 等 AOP 框架相比,ASM 更底层,灵活性更高,但学习曲线更陡峭。Spring 和 AspectJ 提供了更高级别的抽象,使得开发者可以通过更直观的方式定义切面,而不需要直接操作字节码。 总的来...

    CGLIB需要的asm-2.2.3.jar和cglib-nodep-2.2.jar

    ASM-2.2.3是ASM的一个版本,包含了对Java字节码处理的各种工具和API,是CGLIB运行的基础。 CGLIB-nodep-2.2.jar是CGLIB的一个无依赖版本,"nodep"即"no dependency"的缩写,意味着这个版本的CGLIB不包含任何外部...

    CGLib3.2.5依赖包及源码

    CGLib,全称为Code Generation Library,是一个强大的Java字节码操作库,广泛应用于动态代理、AOP(面向切面编程)以及性能优化等领域。它允许开发者在运行时创建和增强新的类或对象,而无需编写任何Java源代码。...

    cglib动态生成java类

    CGLib的核心是ASM库,它能直接操作字节码,从而实现对类的动态生成和修改。 ### 动态代理的实现 1. **Enhancer**:CGLib中的核心类,用于创建代理对象。你可以通过`Enhancer`设置回调函数、目标对象、父类等,然后...

    Asm和cglibjar包

    总结来说,Asm和CGLIB是Java开发中的重要工具,它们提供了对字节码的操纵能力,使得我们可以实现诸如动态代理、AOP等高级编程模式。而MyBatis这样的框架则巧妙地利用了这些库,为开发者提供了方便的数据持久化解决...

    cglib-2.2.jar asm-tree.jar asm-commons.jar asm.jar

    【标题】"cglib-2.2.jar asm-tree.jar asm-commons.jar asm.jar" 提供的是一组用于Java编程的库,它们主要用于实现动态代理和字节码操作。 【描述】"cglib动态代理模式jar包 cglib-2.2.jar asm-tree.jar asm-...

    ASM操作字节码,动态生成Java类class文件

    在Java开发中,ASM库允许我们直接操作字节码,这对于理解和实践AOP(面向切面编程)的概念尤其有用,就像Spring框架中的AOP实现。 面向切面编程(AOP)是一种编程范式,它允许程序员定义“切面”,这些切面封装了...

    Cglib和ASM打包合集

    Cglib和ASM是Java开发中的两个重要库,主要用于动态代码生成和字节码操作。在Java中,当你需要在运行时创建新类或者增强已有类的功能时,这两个库就能发挥巨大作用。以下是对这两个库及其相关文件的详细解释: **...

    Cglib&ASM;打包合集

    Cglib和ASM是Java开发中的两个重要库,它们在处理动态代码生成和字节码操作方面发挥着关键作用。这两个库通常与AOP(面向切面编程)框架如Spring密切相关,同时也被广泛用于性能优化、测试工具以及模拟对象的创建。 ...

Global site tag (gtag.js) - Google Analytics