`
benx
  • 浏览: 272208 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

javassist与classLoader

    博客分类:
  • java
阅读更多

 

javassist.jar是个非常不错的classCode修改框架,简单实用

 

通过javassist和classLoader结合,在加载class时修改class,类似于Spring AOP,可以在指定的class中额外加载指定的功能

 

下面的例子中,在AppClassLoader的classPath中包含的class都加入了方法信息打印(参数打印、方法调用栈),方法返回信息打印。

 

利用这个,如果要看Spring,Hibernate的大点的框架时,通过这个运行一个例子,可以很方便了解方法的调用时序图(调用堆栈),每个参数的值。

 

当然这个例子很简陋,比如打印参数只能打印基本类型,如果是高级对象需要重写,解析。

 

 

 


import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

/**
 * 该类的主要原理是通过类加载时修改classCode,修改的方法可以是对方法的修改,新增,删除,属性的修改,新增删除,等其他操作
 * 通过这个例子,可以很方便的对程序进行日志跟踪,排错,流程理解等
 * 
 * @author jin.xiong
 * 
 */
 public class JavassistLoader extends ClassLoader {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void main(String[] args) throws Throwable {
		JavassistLoader s = new JavassistLoader();
		Class c = s.loadClass("com.benx.Test");
		c.getDeclaredMethod("main", new Class[] { String[].class }).invoke(null, new Object[] { args });
	}

	private ClassPool	pool;

	private ClassLoader	classLoader;

	public JavassistLoader() throws NotFoundException {

		/**
		 * 设置classLoader的parent为ExtClassLoader,如果没有设置,将默认使用AppClassLoader,
		 * 因为classLoader的加载顺序是从parent
		 * --child的相亲委派加载关系,所以如果不设置那么classPath的class将不会使用自定义加载器
		 * 
		 * 如果加载的class为外部的,那么可以不设置parent,使用默认
		 */
		super(Thread.currentThread().getContextClassLoader().getParent());
		classLoader = Thread.currentThread().getContextClassLoader();

		String[] classPath = System.getProperty("java.class.path").split(";");
		pool = ClassPool.getDefault();
		for (String path : classPath) {
			System.out.println(path);
			pool.appendClassPath(path);
		}
		// TODO 可以自定义需要加载的类
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected Class findClass(String name) throws ClassNotFoundException {
		// TODO 可以对class过滤
		try {
			CtClass cc = pool.get(name);
			System.out.println(cc.isFrozen() + "  " + cc.isInterface() + "  " + cc.isModified() + "   " + cc.isPrimitive());
			if (!cc.isInterface()) {
				CtMethod[] ms = cc.getDeclaredMethods();
				for (CtMethod m : ms) {

					if (m.isEmpty())
						continue;
					// TODO 可以对method过滤
					StringBuffer sb = new StringBuffer("");
					sb.append("{");
					// TODO 可以指定修改的内容
					m.insertBefore(getStackTraceCode().toString() + getParaCode(m).toString());

					m.insertAfter(getReturnCode().toString());
					sb.append("}");
				}
			}
			byte[] b = cc.toBytecode();
			return defineClass(name, b, 0, b.length);
		} catch (Exception e) {
			// e.printStackTrace();
			Class cls = classLoader.loadClass(name);
			return cls;
			// throw new ClassNotFoundException();
		}
	}

	private StringBuffer getReturnCode() {
		StringBuffer temp = new StringBuffer("");
		temp.append("StackTraceElement[] as = Thread.currentThread().getStackTrace();");
		temp.append("System.out.println(\"class:\"+as[1].getClassName()+\" method:\"+as[1].getMethodName() +\"  return:\"+$_);");
		return temp;
	}

	/**
	 * 方法参数内容显示的嵌入代码
	 * 
	 * @param cm
	 * @return
	 * @throws NotFoundException
	 */
	private StringBuffer getParaCode(CtMethod cm) throws NotFoundException {
		StringBuffer temp = new StringBuffer("");
		temp.append("		Object[] ob = $args; ");
		temp.append("		StringBuffer sb = new StringBuffer();");
		temp.append("       sb.append(\"[\");");
		temp.append("       for (int i = 0; i < ob.length; i++) {");
		temp.append("            sb.append(ob[i]+\",\");");
		temp.append("       }");
		temp.append("       sb.append(\"]\");");
		temp.append("		System.out.println(\"parameter is:\"+sb);");
		return temp;
	}
	/**
	 * 方法调用栈的嵌入代码
	 * 
	 * @return
	 */
	private StringBuffer getStackTraceCode() {
		StringBuffer sb = new StringBuffer("");
		sb.append("		StackTraceElement[] as = Thread.currentThread().getStackTrace();");
		sb.append("		System.out.print(\"class:\"+as[1].getClassName()+\" method:\"+as[1].getMethodName());");
		sb.append("		StringBuffer temp = new StringBuffer();");
		sb.append("		for (int i = (as.length - 1); i > 0; i--) {");
		sb.append("			temp.append(as[i].getClassName() + \".\" + as[i].getMethodName() + \"   \");");
		sb.append("		}");
		sb.append("		System.out.print(\"   StackTrace:\");");
		sb.append("		System.out.print(temp.toString());");
		return sb;
	}
}
 
分享到:
评论

相关推荐

    开发工具 javassist-3.21.0-GA

    开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发...

    javassist-3.19.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.19.0-GA.jar; 赠送原API文档:javassist-3.19.0-GA-javadoc.jar; 赠送源代码:javassist-3.19.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.19.0-GA.pom; 包含翻译后的API文档...

    javassist-3.23.1-GA-API文档-中文版.zip

    赠送jar包:javassist-3.23.1-GA.jar; 赠送原API文档:javassist-3.23.1-GA-javadoc.jar; 赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档...

    javassist-3.27.0-GA-API文档-中英对照版.zip

    赠送jar包:javassist-3.27.0-GA.jar; 赠送原API文档:javassist-3.27.0-GA-javadoc.jar; 赠送源代码:javassist-3.27.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.27.0-GA.pom; 包含翻译后的API文档...

    javassist-3.24.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.24.0-GA.jar; 赠送原API文档:javassist-3.24.0-GA-javadoc.jar; 赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档...

    javassist-3.23.1-GA-API文档-中英对照版.zip

    赠送jar包:javassist-3.23.1-GA.jar; 赠送原API文档:javassist-3.23.1-GA-javadoc.jar; 赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档...

    javassist-3.21.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.21.0-GA.jar; 赠送原API文档:javassist-3.21.0-GA-javadoc.jar; 赠送源代码:javassist-3.21.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.21.0-GA.pom; 包含翻译后的API文档...

    javassist-3.24.0-GA-API文档-中英对照版.zip

    赠送jar包:javassist-3.24.0-GA.jar; 赠送原API文档:javassist-3.24.0-GA-javadoc.jar; 赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档...

    javassist-3.20.0-GA-API文档-中文版.zip

    赠送jar包:javassist-3.20.0-GA.jar; 赠送原API文档:javassist-3.20.0-GA-javadoc.jar; 赠送源代码:javassist-3.20.0-GA-sources.jar; 包含翻译后的API文档:javassist-3.20.0-GA-javadoc-API文档-中文...

    javassist ognl2.7的依赖包

    动态构造 Java 类, 还有个作用就是性能的提升. 巧用这个方法, 会大大的提升系统的性能.OGNL2.7 版本中就是用javassist 构造对象的访问代码

    javassist-3.18.1-GA-API文档-中文版.zip

    赠送jar包:javassist-3.18.1-GA.jar; 赠送原API文档:javassist-3.18.1-GA-javadoc.jar; 赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档...

    javassist-3.18.1-GA-API文档-中英对照版.zip

    赠送jar包:javassist-3.18.1-GA.jar; 赠送原API文档:javassist-3.18.1-GA-javadoc.jar; 赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档...

    javassist-3.27.0-GA.jar

    javassist-3.27.0-GA.jar

    javassist包

    javassist包

    javassist-3.21.0-GA-API文档-中英对照版.zip

    赠送jar包:javassist-3.21.0-GA.jar; 赠送原API文档:javassist-3.21.0-GA-javadoc.jar; 赠送源代码:javassist-3.21.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.21.0-GA.pom; 包含翻译后的API文档...

    javassist-3.15.0-GA

    javassist版本 javassist-3.15.0-GA

    javassist.jar源码

    javassist-3.7.ga.jar反射类javassist.jar源码

    javassist-3.14.0-GA

    Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作...

    javassistDemo.zip

    javassist的使用,也可直接使用该demo修改自己的jar中的方法,demo中写了两种方法可供参考

    javassist-3.7.ga.jar

    javassist-3.7.ga.jar

Global site tag (gtag.js) - Google Analytics