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

Javassist 实现代码增强

    博客分类:
  • Java
 
阅读更多

 

 

/**
 * Desc:TODO
 * 
 * @author zhangwei<wei.zw@corp.netease.com>
 * @since 2016年1月14日 下午9:19:34
 * @version v 0.1
 */
public final class ClassEnhancedGenerator {
	
	private ClassEnhancedGenerator() {
	}

	/**
	 * 类方法增强<BR>
	 *
	 * 对指定类的方法进行代码增强(将指定的原方法名改为$enhanced,同时复制原方法名进行代码注入)
	 * 
	 * @param className
	 *            待增强的类名
	 * @param methodName
	 *            待增强的方法名
	 * @param provider
	 *            {@link ClassInjectProvider}实现类
	 * @throws Exception
	 */
	public static void enhancedMethod(Class<?> cls, Method[] methods, InjectType injectType, ClassInjectProvider provider)
			throws Exception {
		CtClass ctClass = ClassPool.getDefault().get(cls.getName());
		for (int i = 0; i < methods.length; i++) {
			injectCodeForMethod(ctClass, methods[i].getName(), injectType, provider);
		}
		String resource = cls.getName().replace(".", "/") + ".class";
		URI uri = ClassLoader.getSystemClassLoader().getResource(resource).toURI();
		String classFilePath = uri.getRawPath().substring(0, uri.getRawPath().length() - resource.length());
		ctClass.writeFile(classFilePath);
	}

	/***
	 * 注入增强代码
	 * 
	 * @param ctClass
	 * @param methodName
	 * @param injectType
	 * @param provider
	 * @throws Exception
	 * @author zhangwei<wei.zw@corp.netease.com>
	 */
	private static void injectCodeForMethod(CtClass ctClass, String methodName, InjectType injectType,
			ClassInjectProvider provider) throws Exception {
		CtMethod oldMethod = ctClass.getDeclaredMethod(methodName);
		// 修改原有的方法名称为"方法名$enhanced",如果已存在该方法则返回
		String originalMethod = methodName + "$enhanced";
		CtMethod[] methods = ctClass.getMethods();
		for (int i = 0; i < methods.length; i++) {
			CtMethod method = methods[i];
			if (method.getName().equals(originalMethod)) {
				return;
			}
		}
		oldMethod.setName(originalMethod);
		// 增加代码,复制原来的方法名作为增强的新方法,同时调用原有方法即"方法名$enhanced"
		CtMethod enhancedMethod = CtNewMethod.copy(oldMethod, methodName, ctClass, null);
		// 对复制的方法注入代码
		StringBuffer methodBody = new StringBuffer();
		methodBody.append("{");
		switch (injectType) {
		case BEFORE:
			methodBody.append(provider.injectCode(enhancedMethod));
			methodBody.append("return " + originalMethod + "($$); ");
			break;
		case AFTER:
			methodBody.append("try{");
			methodBody.append("return " + originalMethod + "($$); ");
			methodBody.append("}finally{");
			methodBody.append(provider.injectCode(enhancedMethod));
			methodBody.append("}");
			break;
		default:
			String injectCode = provider.injectCode(enhancedMethod);
			methodBody.append(injectCode);
		}
		methodBody.append("}");
		enhancedMethod.setBody(methodBody.toString());
		ctClass.addMethod(enhancedMethod);
	}
}

 

 

/**
 * Desc:TODO
 * 
 * @author zhangwei<wei.zw@corp.netease.com>
 * @since 2016年1月14日 下午9:21:51
 * @version v 0.1
 */
public interface ClassInjectProvider {

	/**
	 * 对指定的方法注入代码
	 *
	 * @param ctMethod
	 *            CtMethod
	 * @return
	 */
	public String injectCode(final CtMethod ctMethod) throws Exception;

}

 

/**
 * Desc:TODO
 * 
 * @author zhangwei<wei.zw@corp.netease.com>
 * @since 2016年1月14日 下午9:23:17
 * @version v 0.1
 */
public enum InjectType {
	BEFORE, AFTER, REPLACE;
}

 

0
0
分享到:
评论
1 楼 lclkf 2016-01-15  
我用asm做过和你这个一模一样的功能,我这里一个同事和你同名,前两天让他重写了这个功能。- -!

相关推荐

    javaagent+javassist

    javassist是一个开源的Java字节码操作库,它可以动态修改类的字节码,实现运行时代码增强。开发者无需理解复杂的字节码格式,只需使用javassist提供的API,就可以轻松地添加、删除或修改类的方法、字段甚至整个类。...

    javassist+jd-gui

    3. **字节码修改**:可以插入、删除或替换已有的字节码指令,实现代码的动态增强。 4. **类转换**:`javassist` 提供了转换器,可以将类从一种形式转换为另一种形式,例如从 Java 源码转换为字节码。 另一方面,`jd...

    java 反编译工具 jboss-javassist

    4. **面向切面编程(AOP)**:在AOP中,Javassist可以用来动态插入切面代码,实现如日志记录、事务管理等横切关注点。 5. **教学与研究**:由于它可以轻松地反编译和修改字节码,Javassist在教学和研究Java字节码和...

    jboss-javassist和JByteMode整合包

    这样的流程在处理复杂的需求,如热更新、插件系统或者代码增强时非常有用。 **实战示例** 1. **反编译jar包**:使用JByteMode打开.jar文件,反编译出特定类的源代码,这可以帮助我们理解已存在的代码结构,便于后续...

    Javassist18版20版22版的jar包

    - 框架开发:许多自定义框架会使用Javassist来实现动态代码生成,比如ORM框架Hibernate。 - 性能监控:可以通过修改字节码在运行时插入监控代码。 - 测试工具:单元测试框架可能会使用Javassist来模拟方法或改变...

    javassistDemo

    通过定义切点和切面,可以实现灵活的代码结构和解耦。 7. **热部署**:在开发过程中,Javaassist还能用于实现类的热部署,即在不重启应用的情况下更新类的字节码,这对于快速迭代和调试非常有帮助。 8. **代码生成...

    javassist-3.18.1-GA.jar

    在Java世界里,这种技术通常被称为字节码工程,对于实现如AOP(面向切面编程)、动态代理和运行时代码优化等高级功能非常有用。 `javassist-3.18.1-GA.jar`是Javaassist的一个特定版本,GA代表“General ...

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

    总的来说,Java动态代理机制为我们提供了灵活的代码扩展性,可以根据需要选择JDK、CGLIB、Javassist或ASM来实现不同的代理需求。理解并掌握这些技术,能帮助我们在开发过程中更加高效地实现功能扩展和代码解耦。在...

    javassist-3.15.0-GA

    总结来说,"javassist-3.15.0-GA"是Java开发中的一个重要工具,它使得在运行时动态修改和增强Java代码成为可能,广泛应用于AOP、动态代理、代码生成等领域。通过深入理解和熟练运用Javaassist,开发者可以提高代码的...

    javassist-3.7.GA.zip

    在解压"javassist-3.7.GA.zip"后,你会得到"javassist-3.7"目录,其中包含了一系列的JAR文件和文档,这些文件提供了库的实现和相关的API文档。开发者可以通过引入这些JAR到项目中,来利用Javaassist提供的功能。 总...

    javassist-3.20.0-GA.zip

    Javaassist是一个强大的开源库,主要用于在运行时动态地修改Java字节码。它是一个非常实用的工具...通过熟练掌握Javaassist,你可以实现许多原本需要重新编译源代码才能完成的功能,大大提高了开发效率和代码的灵活性。

    javassist 3.23.1版本

    开发者可以通过CtClass的`insertBefore()`、`insertAfter()`和`replace()`等方法来实现代码注入。 3. **字节码操作**:Javaassist 提供了丰富的API来处理字节码,包括读取、解析和生成字节码。这使得开发者能够对类...

    jboss-javassist-javassist-rel_3_23_0_ga-2-gf85a72b

    在 Java 开发中,Javaassist 提供了一种简单的方法来创建和编辑类,这对于实现 AOP(面向切面编程)、动态代理、代码生成以及对现有代码进行热替换等任务非常有用。 首先,Javaassist 提供了一个类似于 Java 语法的...

    javassist-3.7.ga.jar

    例如,可以通过 `CtMethod.insertAt()` 方法在特定位置插入字节码,实现方法的动态增强。 3. **代码生成**:Javaassist 提供了类似于 Java 语法的 API 来生成字节码。`CtNewMethod` 和 `CtNewConstructor` 可以帮助...

    javassist-3.7.ga.jar下载

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

    javassist-3.9.0.GA.jar.zip

    在这些场景下,Javaassist帮助实现了动态织入增强代码、元数据驱动的代码生成等复杂功能。 总的来说,"javassist-3.9.0.GA.jar.zip"提供的Javaassist库是一个强大的字节码操作工具,对于理解Java字节码以及在运行时...

    Javassist学习手册

    Javassist 是一款功能强大的 Java 字节码操作工具库,它可以动态地修改类结构、方法体等,从而实现类的增强、代理等功能。这对于框架开发、AOP、动态代理等领域具有重要意义。本文将详细介绍 Javassist 的基本概念、...

    javassist-3.18.0-ga

    4. **反射增强**:Javaassist可以作为Java反射机制的补充,提供更强大的功能。它不仅能够获取类的信息,还能在运行时动态修改类的行为,这是Java反射API无法做到的。 5. **性能优化**:在某些情况下,使用Java...

    javassist3.9GA

    例如,你可以使用Javaassist来实现一个类增强器,为现有类添加新的行为,而无需重新编译源代码。 在"javassist-3.9.0"这个压缩包中,包含的是Javaassist的3.9.0稳定版本的库文件。这个版本可能修复了之前版本的一些...

    javassist-3.18.2-GA.jar

    总的来说,`javassist-3.18.2-GA.jar` 是一个强大的工具,可以帮助开发者在运行时灵活地调整和扩展 Java 应用程序,提高代码的灵活性和可维护性。它的使用需要一定的字节码知识,但一旦掌握,就能极大地提升开发效率...

Global site tag (gtag.js) - Google Analytics