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

高级字节码生成工具 — Javassist

    博客分类:
  • Java
阅读更多

AOP系列文章:
      Spring AOP:http://ray-yui.iteye.com/blog/2024759
               CGLIB:http://ray-yui.iteye.com/blog/2026426
          Javassist:http://ray-yui.iteye.com/blog/2029261


      Javassist是一个强大的高性能的代码生成包,和CGLIB一样成为众多框架的动态代理解决方案,和CGLIB同样拥有不需要实现接口即可进行动态代理的特点,而且还支持动态生成Java代码,动态实现代理逻辑等强大功能


      使用Javassist生成动态代理可以使用两种方式,一种是使用代理工厂创建,和普通的JDK动态代理和CGLIB类似,另一种则可以使用动态代码创建


      使用工厂创建动态代理例子

public class TestMain {
	@SuppressWarnings("unchecked")
	@Test
	public void testJavassistFactoryProxy() throws Exception {
		// 创建代理工厂
		ProxyFactory proxyFactory = new ProxyFactory();

		// 设置被代理类已实现接口(可选)
		// proxyFactory.setInterfaces(new Class[] {});

		// 设置被代理类的类型
		proxyFactory.setSuperclass(RayTest.class);

		// 创建代理类型的Class
		Class<ProxyObject> proxyClass = proxyFactory.createClass();

		// 注意若然父类没有无参构造函数,需要使用createClass方法的重載
		// RayTest proxyTest = (RayTest) proxyFactory.create(new Class[] {
		// Integer.class }, new Object[] { 0 });

		RayTest proxyTest = (RayTest) proxyClass.newInstance();

		((ProxyObject) proxyTest).setHandler(new MethodHandler() {

			// 真实主題
			RayTest test = new RayTest();

			@Override
			public Object invoke(Object self, Method thisMethod,
					Method proceed, Object[] args) throws Throwable {
				String before = "before ";
				Object str = thisMethod.invoke(test, args);
				String after = " after";
				return before + str + after;
			}
		});

		Assert.assertEquals("before execute after", proxyTest.execute());
	}
}


      上述代码和JDK动态代理和CGLIB的使用方式非常相似,但创建动态代理效率不如JDK动态,以下为动态字节生成动态代理例子

public class TestMain {

	@SuppressWarnings("unchecked")
	@Test
	public void testJavassistDenfinClass() throws Exception {
		// 创建类池,true为使用默认路径
		ClassPool classPool = new ClassPool(true);

		String className = RayTest.class.getName();
		CtClass ctClass = classPool.makeClass(className + "JavassitProxy");

		// 添加接口,可选
		// ctClass.addInterface(classPool.get(RayTestInterface.class.getName()));

		// 添加超类
		ctClass.setSuperclass(classPool.get(RayTest.class.getName()));

		// 添加默认构造函数
		ctClass.addConstructor(CtNewConstructor.defaultConstructor(ctClass));

		// 添加屬性
		ctClass.addField(CtField.make("public " + className + " real = new "
				+ className + "();", ctClass));

		// 添加方法,里面进行动态代理logic
		ctClass.addMethod(CtNewMethod
				.make("public String execute(){ return \"before \" + real.execute() + \" after\";}",
						ctClass));

		Class<RayTest> testClass = ctClass.toClass();
		RayTest test = testClass.newInstance();
		Assert.assertEquals("before execute after", test.execute());

	}
}


      上述例子中使用Javassist的API成功组织出代理类的一个子类,可以看出添加构造函数,增加属性,增加方法,内容都是使用字符串类型即可完成,通过Javassist强大的字节生成能力可以达到动态增加类和实现动态代理的功能,Javassist的动态生成类功能除了应用在动态代理还有很多其他地方可以使用,请读者在实际项目场景灵活运用
5
3
分享到:
评论

相关推荐

    javassist,Java字节码工程工具包.zip

    1. **字节码生成**:Javassist能够生成新的类或方法的字节码,这对于实现动态类型或者运行时代码生成非常有用。它提供了一种类似于Java语法的API来创建和编辑类,使得生成字节码的过程更加直观和易于理解。 2. **类...

    Javassist如何操作Java 字节码

    总结,Javassist提供了一种高级的接口来处理Java字节码,使得开发者能够轻松地进行动态类生成和修改,而无需深入了解字节码底层细节。对于需要实现AOP、代码生成或运行时修改类的场景,Javassist是一个非常实用的...

    JAVA字节码操作库 BCEL

    2. **字节码生成**:BCEL提供了一套接口和类,使得开发者可以动态地生成字节码,这对于创建动态代理、AOP(面向切面编程)等场景非常有用。 3. **代码优化**:通过修改字节码,BCEL可以实现代码的优化,例如去除...

    jboss-javassist和JByteMode整合包

    通过Javassist,我们可以方便地生成和修改类的字节码,从而实现AOP(面向切面编程)等高级功能。它的主要特性包括: 1. 提供了类似于C/C++的API,使得字节码操作更加直观。 2. 支持处理类、接口、方法、字段等元数据...

    面向Java锁机制的字节码自动重构框架.zip

    例如,ASM、ByteBuddy和Javassist等库可以用来动态生成和修改字节码。在重构过程中,需要考虑并发模型、死锁检测、活锁和饥饿等问题,以确保重构后的代码在多线程环境下仍然正确且高效。 字节码自动重构的优势在于...

    javassist-3.18.0-ga

    3. **字节码生成**:Javaassist可以生成新的字节码,这使得在运行时创建新的类或接口成为可能。例如,它可以用于动态生成数据访问对象(DAO),或者根据需要创建特定的代理类。 4. **反射增强**:Javaassist可以...

    javassist-3.9.0.GA.jar.zip

    4. **字节码生成(Bytecode Generation)**:除了修改现有的类,Javaassist还可以完全从头构建新的类。这在生成动态类型或者模拟特定行为时非常有用。 5. **兼容性与效率**:Javaassist设计时考虑了与Java虚拟机的...

    javassist-3.18.1-GA.jar

    总的来说,`javassist-3.18.1-GA.jar`是Javaassist库的一个稳定版本,提供了丰富的API和工具,用于在运行时操纵Java类的字节码。这对于理解和实现诸如Hibernate这样的高级框架的内部工作原理非常有帮助。通过阅读...

    javassist-3.15.0-GA

    - **字节码操作**:Javaassist通过字节码操作实现对类的修改,它可以解析.class文件,并允许用户以Java语法修改字节码。 2. **使用场景**: - **AOP(面向切面编程)**:在不修改源代码的情况下,插入切面代码,...

    javassist-3.7.ga.jar

    2. **字节码生成**:Javaassist 提供了高级的API,允许开发者以类似于Java语法的方式来生成和操作字节码。这对于实现AOP(面向切面编程)或者动态代理等高级功能非常有用。 3. **类转换**:Javaassist 可以将字节码...

    javassist18,20,22三个版本.zip

    Javaassist库提供了一个高级接口,允许开发者无需直接处理字节码指令就能修改或生成类。它通过解析.class文件为用户提供了类的表示,并提供了API来操作这些类。 2. **版本差异**: - **javassist-3.18.0-ga**:这...

    动态代理-jdk、cglib、javassist.zip

    相比于CGLIB,javassist提供了更高级的API,可以直接编辑类的字节码,而不仅仅是生成新的字节码。它不仅可以用作动态代理,还可以用于AOP(面向切面编程)和其他需要修改已有代码的行为。使用javassist创建动态代理...

    基于 javaagent 对 java 原生类的 方法进行字节码动态修改, 以此引发的一些关于 绕过 Java 软件.zip

    Javaagent 是 Java 提供的一种强大的工具,允许在程序运行时对字节码进行修改或增强,从而实现诸如性能监控、代码覆盖测试、安全控制等多种功能。在这个特定的场景中,我们关注的是如何利用 javaagent 来对 Java ...

    javassist-3.7.ga.jar下载

    总的来说,`javassist-3.7.ga.jar`是Java开发中的一个重要工具,它提供了一种强大的方式来处理运行时的字节码,使得代码增强和动态生成变得简单。对于需要在运行时修改类或实现复杂功能的开发者来说,Javaassist是一...

    javassist 包

    3. 类加载器:在运行时,Javaassist使用自定义的类加载器 (`ClassPool` 中的 `makeClass` 方法) 将修改后的字节码转换为实际的Java类并加载到JVM中。 4. 代码生成:Javaassist提供了类似于Java语法的API,可以方便...

    一个牛逼的 Java 字节码类库!(csdn)————程序.pdf

    在Java中,我们可以通过API来操作字节码,实现动态代码生成、字节码注入等高级功能。本文主要介绍了一个强大的Java字节码处理类库——Javaassist。 Javaassist是一个开源库,允许开发者在运行时动态地修改或者创建...

    Javassist.jar

    1. **字节码操作**:Javaassist提供了一套API,使得程序员可以创建新的类,修改现有类的方法,甚至在运行时动态生成类的字节码。这对于那些需要在运行时自定义行为的场景非常有用,比如实现插件系统或者创建代理对象...

    magic:Java 编码异常(不安全、反射、双向原生、JVM 字节码生成)。 这是 Just4Fun

    "magic:Java 编码异常(不安全、反射、双向原生、JVM 字节码生成)"这个标题正是涵盖了这四个核心主题,下面我们将逐一探讨。 首先,**不安全的编码**通常指的是那些可能导致程序安全性问题的编程实践。这可能包括...

    jclasslib反编译工具包,修改class文件

    - 对于复杂的字节码操作,可能需要结合其他的工具如ASM、Javassist等进行。 总的来说,jclasslib是一款强大的Java字节码分析工具,它使得开发者能够深入到程序运行的本质,对Java Class文件进行探索和修改,从而...

    JavaBytecodeAnalyzer:解析学习 Java 字节码

    - 开源库如ASM、BCEL、Javassist:提供了API,可以直接操作和生成字节码。 - IntelliJ IDEA和Eclipse等IDE也提供了查看字节码的功能。 掌握Java字节码分析能力对Java开发者来说是一项高级技能,它不仅可以提升你...

Global site tag (gtag.js) - Google Analytics