- 浏览: 276162 次
- 性别:
- 来自: 北京
最新评论
-
gotosuzhou:
好的 谢谢分享
Spring 事务异常回滚 -
cd249745647:
哈哈
Spring MVC REST 例子 -
向日葵上的小蜜蜂:
代码都差不多贴出来了,为啥不直接提供下载呢
Spring MVC REST 例子 -
he3109006290:
我猜它应该有个算法,当出现长时间处理的情况的,它自动会启动另外 ...
netty 疑惑 -
yanghoho6:
很好, 学习了,
oracle基本的索引概念.doc
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; } }
发表评论
-
自增 自减 java和c的区别
2012-03-10 15:57 1439JAVA public class Test { ... -
瞎聊系统性能优化
2012-02-19 23:46 1143一个系统中影响性能的无非就是CPU计算能力,磁盘、网络的读写能 ... -
在tomcat中,通过IP访问web系统,不需要端口号的方法(转)
2012-02-06 11:10 8883源文章地址:http://sinian.iteye.com/b ... -
java 编码
2012-02-02 18:23 1164先看一个字符串 String str = &qu ... -
tcp 和 java socket
2011-12-31 12:52 2813tcp socket 总结点 1 ... -
netty 疑惑
2011-12-01 18:27 2701netty的nio 模式如下 一个线程Boss使用 ... -
Apache Tomcat http_proxy 连接方式配置
2011-11-02 18:03 56021、安装Tomcat ,为了使域名保持一致,在conf\Cat ... -
谈线程池
2011-10-27 12:47 1518线程池原理:用指定数 ... -
设置tomcat启动参数
2011-09-15 16:58 1522window: 在catalina.bat 文件的开始处添加如 ... -
通过反汇编class看i++和++i的区别
2011-08-17 14:32 2106public void method4() ... -
hotspot 控制参数
2011-08-17 09:25 1299文档来源于 http://www.oracle.com ... -
Spring 事务异常回滚
2011-08-16 10:10 11132先看如下代码 @Transactional ... -
java IO和NIO测试
2011-08-11 12:08 1606测试环境:cpu:Q9500 4核 频率2.83GHZ ... -
静态锁和实例锁
2011-07-28 18:21 1948Java中可以对静态方法和实例方法使用synchroni ... -
BASE64 和Dom4j
2011-07-20 09:45 1299项目当中用到MD5做消息摘要,后通过BASE64转成字符 ... -
jetty httpServer和java6内置httpServer比较
2011-07-19 12:03 3057测试情况是客户端100个线程同时同时请求10000次,服务器端 ... -
Jetty HttpClent 异常
2011-07-15 13:48 1231使用Jetty HttpClent做异步请求,结果发现这 ... -
关于Hibernate延迟加载
2011-07-14 17:42 1083package com.lottery.test; ... -
Jetty内嵌Http服务器
2011-07-14 11:13 3388本例只是以HttpServlet方式实现,更多的方式可以通过h ... -
java concurrent包理解
2011-07-06 12:08 5971Java并发处理 <!--[if !suppor ...
相关推荐
将`javaagent`与`javassist`结合使用,可以实现强大的功能。例如,我们可以通过javaagent在程序启动时注入javassist生成的代码,以实现对目标类的动态增强。以下是一个简单的示例: 1. 创建一个`javaagent`,定义一...
在本文中,我们将深入探讨Javassist如何实现代码注入,并结合实例`HotPatchDemo`来展示其实现过程。 首先,理解代码注入的基本概念是必要的。代码注入是一种技术,允许在程序运行时向现有代码中插入新的行为或修改...
- **类加载器集成**:与Java的ClassLoader协同工作,可以在运行时修改并加载修改后的类。 - **高级API**:提供了高级的API来操作类,如类型转换、注解处理、异常处理等。 - **兼容性**:支持JDK1.3及以上版本,...
`javassist-3.7.ga.jar` 文件是 Javaassist 库的一个版本,版本号为 3.7 GA(General Availability),意味着这是一个公开可用的稳定版本。 Javaassist 提供了一系列的 API,使得开发者可以方便地读取、修改和创建 ...
这个"javassist3.9GA"版本是Javaassist的一个发行版本,主要目的是清理从字节码类文件中测试代码。这个过程对于构建可维护和高效的软件系统尤其重要,因为测试代码通常会在生产环境中增加不必要的负担。 Javaassist...
6. **兼容性**:Javassist与Java标准库的`java.lang.ClassLoader`和`java.lang.reflect`紧密集成,因此可以无缝地与其他Java应用和库配合使用。同时,它支持从Java 1.4到最新的Java版本,确保了广泛的兼容性。 7. *...
此方法能解决所有类的`serialVersionUID`问题,但如果类的属性类型发生变化,仅修改`serialVersionUID`是不够的,因为`serialVersionUID`的变更不仅与类的标识有关,还与类的属性和方法相关。 5. **使用`...
热部署插件的实现原理主要是通过Agent字节码增强、Javassist、Classloader等技术来实现的。Agent字节码增强是指在Java字节码中插入一些用于热部署的代码,以便在运行时可以实现热部署。Javassist是一个Java库,提供...
collection-agent 通过javaagent和javassist技术实现对java的ArrayList和HashMap的增强,在操作集合元素时判断集合...agent的代码与你的main方法在同一个JVM中运行,并被同一个system classloader装载,被同一的安全
3. **Javassist**:除了字节码操作,Javassist还提供了扫描类的能力,可以用于动态修改类。 五、实战示例 以下是一个简单的文件系统扫描示例: ```java import java.io.File; import java.io.FilenameFilter; ...
在Java中,类是由ClassLoader加载的,当一个类被加载后,如果该类的.class文件被修改,ClassLoader可以重新加载这个修改后的类,从而实现运行时的代码更新。但是,需要注意的是,热更新并非总是可行的,有些复杂的...
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { // 字节码操作逻辑 } } ``` ### 4. Dynamic ...
默认的`ClassLoader`无法加载内存中的`.class`,所以我们需要自定义一个`ClassLoader`,覆盖`findClass()`方法,从内存中读取`.class`字节码。 8. **创建并执行实例**: 使用`Class.forName()`加载类后,可以调用`...
Java的`javac`工具可用于编译源代码,`ASM`或`Javassist`库可以方便地操作字节码。 5. Maven插件支持 在开发环境中,我们可以使用Maven的`maven-compiler-plugin`和`maven-surefire-plugin`等插件配置热加载。例如...
然后,使用`java.lang.ClassLoader`的`defineClass`方法将字节码转换为`java.lang.Class`对象。接下来,获取到需要修改的方法,这可以通过反射API完成,如`Class.getMethod`。一旦找到了目标方法,你可以使用`...
在Java编程语言中,`ClassLoader`是一个至关重要的组件,它负责加载类到JVM(Java虚拟机)中。`FakeClassloader`是一个特殊设计的类加载器,它允许开发者进行全局代理,覆盖常规的类加载行为,使得我们可以对类、...
1. 反射与 javassist 2. 反射与工厂模式、java.lang.reflect.* 序列化 1. 什么是序列化与反序列化、为什么序列化 2. 序列化底层原理 3. 序列化与单例模式 4. protobuf 5. 序列化并不安全 注解 1. 元注解、自定义...
在这个场景中,我们关注的是一个名为"seachClass.zip"的压缩包,它显然与Java编程语言中的类(Class)文件有关。Java类文件是编译后Java源代码的结果,用于在Java虚拟机(JVM)上运行。这个压缩包可能包含了多个....
这些库允许程序在运行时动态生成或修改字节码,然后通过ClassLoader加载到JVM中,使得修改后的字节码影响目标进程的执行流程。 2. **应用场景**: - **AOP(面向切面编程)**:在不修改原有代码的情况下,通过字节...