本文目录导读:

我将为你提供几个Javassist的实际应用案例,涵盖从基础到高级的用法。
基础案例:动态创建类和修改方法
1 创建新类
import javassist.*;
import java.lang.reflect.Method;
public class CreateClassExample {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
// 创建一个新的类
CtClass cc = pool.makeClass("com.example.DynamicClass");
// 添加字段
CtField nameField = CtField.make("private String name;", cc);
cc.addField(nameField);
// 添加构造函数
CtConstructor constructor = new CtConstructor(
new CtClass[]{pool.get("java.lang.String")}, cc);
constructor.setBody("{ this.name = $1; }");
cc.addConstructor(constructor);
// 添加方法
CtMethod getNameMethod = CtMethod.make(
"public String getName() { return name; }", cc);
cc.addMethod(getNameMethod);
// 将类转化为字节码并加载
Class<?> clazz = cc.toClass();
// 实例化并调用方法
Object instance = clazz.getDeclaredConstructor(String.class)
.newInstance("张三");
Method getName = clazz.getMethod("getName");
System.out.println("姓名: " + getName.invoke(instance));
// 清理临时类
cc.detach();
}
}
2 修改现有方法
import javassist.*;
public class ModifyMethodExample {
public static class UserService {
public String getUserInfo(String userId) {
return "查询用户: " + userId;
}
}
public static void main(String[] args) throws Exception {
StringBuilder modifiedCode = new StringBuilder();
modifiedCode.append("return \"[增强]\" + ")
.append("$0.getUserInfo($1)")
.append(" + \"[耗时统计]\";");
// 关键:使用自定义ClassLoader加载修改后的类
// 这里使用不同的ClassPool来避免污染原生类
ClassPool pool = new ClassPool();
pool.insertClassPath(new ClassClassPath(UserService.class));
CtClass cc = pool.get(UserService.class.getName());
CtMethod method = cc.getDeclaredMethod("getUserInfo");
method.setBody(modifiedCode.toString());
// 转换为字节码
byte[] byteCode = cc.toBytecode();
cc.detach();
// 使用自定义ClassLoader加载
ModifiedClassLoader classLoader = new ModifiedClassLoader();
Class<?> modifiedClass = classLoader.defineClass(
UserService.class.getName(), byteCode);
// 测试修改后的类
Object instance = modifiedClass.getDeclaredConstructor().newInstance();
Method method2 = modifiedClass.getMethod("getUserInfo", String.class);
System.out.println(method2.invoke(instance, "001"));
}
static class ModifiedClassLoader extends ClassLoader {
public Class<?> defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
}
AOP拦截器案例
一个完整的AOP拦截器实现,用于方法监控和日志记录:
import javassist.*;
import java.lang.annotation.*;
// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Loggable {
String value() default "";
}
// 示例业务类
public class BusinessService {
public void processOrder(String orderId, double amount) {
System.out.println("处理订单: " + orderId + ", 金额: " + amount);
}
public String getUser(String userId) {
System.out.println("获取用户信息: " + userId);
return "用户" + userId;
}
}
// AOP增强工具类
public class AopEnhancer {
private static final String CLASS_PREFIX = "Enhanced_";
public static Object createEnhancedInstance(Class<?> targetClass)
throws Exception {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(targetClass));
// 创建增强类的字节码
String enhancedClassName = CLASS_PREFIX + targetClass.getSimpleName();
CtClass enhancedClass = pool.makeClass(enhancedClassName);
// 继承原始类
enhancedClass.setSuperclass(pool.get(targetClass.getName()));
// 获取所有公共方法
for (Method method : targetClass.getMethods()) {
if (method.getDeclaringClass() == Object.class &&
!isSpecialMethod(method)) {
continue;
}
// 简单判断:只处理包含@Loggable注解的方法或特定方法
if (method.getDeclaringClass() == targetClass) {
// 为每个方法添加日志增强
CtMethod ctMethod = new CtMethod(
pool.get(method.getReturnType().getName()),
method.getName(),
getParameterTypes(pool, method.getParameterTypes()),
enhancedClass);
// 生成增强的方法体
String enhancedBody = generateEnhancedMethod(
method.getName(), method.getReturnType(),
method.getParameterTypes().length);
ctMethod.setBody(enhancedBody);
enhancedClass.addMethod(ctMethod);
}
}
// 生成实例
Class<?> clazz = enhancedClass.toClass();
enhancedClass.detach();
return clazz.getDeclaredConstructor().newInstance();
}
private static String generateEnhancedMethod(String methodName,
Class<?> returnType, int paramCount) {
StringBuilder body = new StringBuilder();
// 拼接参数列表
String params = "";
if (paramCount > 0) {
StringBuilder paramNames = new StringBuilder();
for (int i = 1; i <= paramCount; i++) {
if (i > 1) paramNames.append(", ");
paramNames.append("$").append(i);
}
params = paramNames.toString();
}
// 开始时间
body.append("long startTime = System.nanoTime();\n");
body.append("System.out.println(\"[AOP] 进入方法: " + methodName + "\");\n");
// 返回值处理
if (returnType == void.class) {
body.append("super." + methodName + "(" + params + ");\n");
} else {
body.append("Object result = super." + methodName +
"(" + params + ");\n");
body.append("System.out.println(\"[AOP] 方法返回值: \" + result);\n");
}
// 结束时间
body.append("long endTime = System.nanoTime();\n");
body.append("System.out.println(\"[AOP] 执行耗时: \" + " +
"(endTime - startTime) / 1000000.0 + \"ms\");\n");
body.append("System.out.println(\"[AOP] 退出方法: " + methodName + "\");\n");
// 返回值
if (returnType != void.class) {
if (returnType == boolean.class) {
body.append("return ((Boolean)result).booleanValue();\n");
} else if (returnType == int.class || returnType == long.class ||
returnType == double.class || returnType == float.class ||
returnType == short.class || returnType == byte.class) {
body.append("return ((Number)result).");
if (returnType == int.class) body.append("intValue()");
else if (returnType == long.class) body.append("longValue()");
else if (returnType == double.class) body.append("doubleValue()");
else if (returnType == float.class) body.append("floatValue()");
else if (returnType == short.class) body.append("shortValue()");
else body.append("byteValue()");
body.append(";\n");
} else {
body.append("return (" + returnType.getName() + ")result;\n");
}
}
return body.toString();
}
private static boolean isSpecialMethod(Method method) {
String name = method.getName();
return name.equals("toString") || name.equals("hashCode") ||
name.equals("equals") || name.equals("getClass") ||
name.equals("wait") || name.equals("notify") ||
name.equals("notifyAll");
}
private static CtClass[] getParameterTypes(ClassPool pool,
Class<?>[] params) throws NotFoundException {
CtClass[] ctParams = new CtClass[params.length];
for (int i = 0; i < params.length; i++) {
ctParams[i] = pool.get(params[i].getName());
}
return ctParams;
}
public static void main(String[] args) throws Exception {
// 使用示例
Object enhancedService = createEnhancedInstance(BusinessService.class);
BusinessService service = (BusinessService) enhancedService;
service.processOrder("ORD-001", 100.50);
service.getUser("U001");
}
}
动态代理替代方案
Javassist实现比JDK动态代理更快的方式:
import javassist.*;
import java.util.concurrent.ConcurrentHashMap;
public class FastProxyExample {
interface UserService {
void save(String name);
String get(Integer id);
}
static class UserServiceImpl implements UserService {
public void save(String name) {
System.out.println("保存用户: " + name);
}
public String get(Integer id) {
return "用户ID: " + id;
}
}
private static final ConcurrentHashMap<String, Class<?>> proxyCache =
new ConcurrentHashMap<>();
public static <T> T createProxy(Class<T> interfaceClass,
T target, InvocationHandler handler) throws Exception {
String proxyClassName = "Proxy_" + interfaceClass.getSimpleName() +
System.nanoTime();
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(target.getClass()));
// 创建代理类
CtClass proxyClass = pool.makeClass(proxyClassName);
proxyClass.addInterface(pool.get(interfaceClass.getName()));
// 添加目标对象引用
CtClass targetClass = pool.get(target.getClass().getName());
CtField targetField = new CtField(targetClass, "target", proxyClass);
proxyClass.addField(targetField);
// 添加handler字段
CtClass handlerClass = pool.get(InvocationHandler.class.getName());
CtField handlerField = new CtField(handlerClass, "handler", proxyClass);
proxyClass.addField(handlerField);
// 添加构造函数
CtConstructor constructor = new CtConstructor(
new CtClass[]{targetClass, handlerClass}, proxyClass);
constructor.setBody("{ this.target = $1; this.handler = $2; }");
proxyClass.addConstructor(constructor);
// 为接口的每个方法添加实现
for (Method method : interfaceClass.getMethods()) {
String methodName = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
Class<?> returnType = method.getReturnType();
// 创建方法签名
StringBuilder signature = new StringBuilder();
signature.append("public ");
signature.append(returnType.getName()).append(" ");
signature.append(methodName).append("(");
if (paramTypes.length > 0) {
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) signature.append(", ");
signature.append(paramTypes[i].getName())
.append(" arg").append(i);
}
}
signature.append(")");
// 方法体
StringBuilder body = new StringBuilder();
body.append("{ ");
// 构造参数数组
body.append("Object[] args = new Object[] { ");
if (paramTypes.length > 0) {
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) body.append(", ");
body.append("arg").append(i);
}
}
body.append(" };");
// 调用handler
body.append(" Object result = handler.invoke(target, " +
"getClass().getMethod(\"" + methodName + "\", ");
// 参数类型数组
if (paramTypes.length > 0) {
body.append("new Class[]{");
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) body.append(", ");
body.append(paramTypes[i].getName()).append(".class");
}
body.append("}");
} else {
body.append("new Class[0]");
}
body.append("), args);");
// 返回值处理
if (returnType == void.class) {
body.append(" }");
} else if (returnType.isPrimitive()) {
if (returnType == boolean.class) {
body.append(" return ((Boolean)result).booleanValue(); }");
} else if (returnType == int.class) {
body.append(" return ((Integer)result).intValue(); }");
} else if (returnType == long.class) {
body.append(" return ((Long)result).longValue(); }");
} else if (returnType == double.class) {
body.append(" return ((Double)result).doubleValue(); }");
} else if (returnType == float.class) {
body.append(" return ((Float)result).floatValue(); }");
} else if (returnType == short.class) {
body.append(" return ((Short)result).shortValue(); }");
} else if (returnType == byte.class) {
body.append(" return ((Byte)result).byteValue(); }");
} else {
body.append(" return ((Character)result).charValue(); }");
}
} else {
body.append(" return (" + returnType.getName() + ")result; }");
}
// 添加方法
CtMethod ctMethod = CtMethod.make(
signature.toString() + " " + body.toString(), proxyClass);
proxyClass.addMethod(ctMethod);
}
// 创建代理实例
@SuppressWarnings("unchecked")
T proxy = (T) proxyClass.toClass()
.getDeclaredConstructor(target.getClass(),
InvocationHandler.class)
.newInstance(target, handler);
proxyClass.detach();
return proxy;
}
@FunctionalInterface
interface InvocationHandler {
Object invoke(Object target, Method method, Object[] args)
throws Throwable;
}
public static void main(String[] args) throws Exception {
UserServiceImpl target = new UserServiceImpl();
// 创建代理
UserService proxy = createProxy(UserService.class, target,
(proxyObj, method, methodArgs) -> {
System.out.println("[代理] 方法: " + method.getName());
long start = System.currentTimeMillis();
try {
return method.invoke(proxyObj, methodArgs);
} finally {
System.out.println("[代理] 耗时: " +
(System.currentTimeMillis() - start) + "ms");
}
});
// 测试代理
proxy.save("测试用户");
System.out.println(proxy.get(1));
}
}
缓存框架实现
使用Javassist实现简单的方法缓存:
import javassist.*;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CacheExample {
static class DataService {
public String getData(String key) {
// 模拟耗时操作
try { Thread.sleep(1000); } catch (Exception e) {}
return "数据-" + key;
}
public int calculate(int x, int y) {
try { Thread.sleep(500); } catch (Exception e) {}
return x * y + x + y;
}
}
static class CacheManager {
private Map<String, Object> cache = new ConcurrentHashMap<>();
public Object get(String key) {
return cache.get(key);
}
public void put(String key, Object value) {
cache.put(key, value);
}
public boolean contains(String key) {
return cache.containsKey(key);
}
}
public static void main(String[] args) throws Exception {
// 原始服务
DataService original = new DataService();
// 带缓存的服务
DataService cached = createCachedService(original);
// 第一次调用(执行实际逻辑)
System.out.println("第一次调用:");
long start = System.currentTimeMillis();
System.out.println(cached.getData("key1"));
System.out.println("耗时: " + (System.currentTimeMillis() - start) + "ms");
// 第二次调用(命中缓存)
System.out.println("\n第二次调用:");
start = System.currentTimeMillis();
System.out.println(cached.getData("key1"));
System.out.println("耗时: " + (System.currentTimeMillis() - start) + "ms");
// 多参数方法
System.out.println("\n多参数方法:");
start = System.currentTimeMillis();
System.out.println("calculate(3,4) = " + cached.calculate(3, 4));
System.out.println("耗时: " + (System.currentTimeMillis() - start) + "ms");
start = System.currentTimeMillis();
System.out.println("calculate(3,4) = " + cached.calculate(3, 4));
System.out.println("耗时: " + (System.currentTimeMillis() - start) + "ms");
}
private static DataService createCachedService(DataService service)
throws Exception {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(service.getClass()));
// 创建缓存服务类
CtClass cachedClass = pool.makeClass("Cached_" +
System.nanoTime());
cachedClass.setSuperclass(pool.get(DataService.class.getName()));
// 添加缓存管理器
CtField cacheField = CtField.make(
"private static CacheManager cacheManager = " +
"new CacheManager();", cachedClass);
cachedClass.addField(cacheField);
// 使用annotation或者简单约定:需要缓存的方法
java.lang.reflect.Method[] methods = DataService.class.getMethods();
for (Method method : methods) {
if (method.getDeclaringClass() == DataService.class &&
isCacheable(method.getName())) {
StringBuilder body = new StringBuilder();
String methodName = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
// 构建缓存key
body.append("{ ");
body.append("StringBuilder key = new StringBuilder(\"");
body.append(methodName);
body.append("(\");");
if (paramTypes.length > 0) {
for (int i = 1; i <= paramTypes.length; i++) {
if (i > 1) body.append(" key.append(\",\");");
body.append(" key.append($").append(i).append(");");
}
}
body.append(" key.append(\")\");");
body.append("String cacheKey = key.toString();");
// 检查缓存
body.append("if (cacheManager.contains(cacheKey)) {");
body.append("System.out.println(\"[缓存] 命中缓存: \" + cacheKey);");
body.append("return (" + method.getReturnType().getName() +
") cacheManager.get(cacheKey);");
body.append("}");
// 调用原方法
body.append("System.out.println(\"[缓存] 未命中,执行方法...\");");
String result = "结果";
if (method.getReturnType() != void.class) {
body.append("Object " + result + " = ");
}
// 构建调用参数
StringBuilder params = new StringBuilder();
if (paramTypes.length > 0) {
for (int i = 1; i <= paramTypes.length; i++) {
if (i > 1) params.append(", ");
params.append("$").append(i);
}
}
if (method.getReturnType() != void.class) {
body.append("super." + methodName + "(" + params + ");");
// 存入缓存
body.append("cacheManager.put(cacheKey, " + result + ");");
body.append("return (" + method.getReturnType().getName() +
") " + result + ";");
} else {
body.append("super." + methodName + "(" + params + ");");
}
body.append("}");
// 创建方法
CtMethod ctMethod = new CtMethod(
pool.get(method.getReturnType().getName()),
methodName,
getCtParamTypes(pool, paramTypes),
cachedClass);
ctMethod.setBody(body.toString());
cachedClass.addMethod(ctMethod);
}
}
// 添加CacheManager类到类池
pool.importPackage("java.util.concurrent");
pool.importPackage("java.util");
// 加载CacheManager类
ClassPool.getDefault().appendClassPath(new ClassClassPath(
CacheManager.class));
// 创建实例
Class<?> clazz = cachedClass.toClass();
cachedClass.detach();
return (DataService) clazz.getDeclaredConstructor().newInstance();
}
private static boolean isCacheable(String methodName) {
return methodName.equals("getData") || methodName.equals("calculate");
}
private static CtClass[] getCtParamTypes(ClassPool pool,
Class<?>[] params) throws NotFoundException {
CtClass[] types = new CtClass[params.length];
for (int i = 0; i < params.length; i++) {
types[i] = pool.get(params[i].getName());
}
return types;
}
}
性能监控案例
import javassist.*;
public class PerformanceMonitor {
public static void monitorMethod(String className, String methodName) {
try {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(className);
// 获取要监控的方法
CtMethod method = cc.getMethod(methodName, "()V");
// 存储原始方法体
final String originalBody = method.getMethodInfo()
.getCodeAttribute().getCode().toString();
// 构建监控包装
method.setBody(buildMonitorBody(methodName, originalBody, false));
// 转换类
cc.toClass();
} catch (Exception e) {
e.printStackTrace();
}
}
private static String buildMonitorBody(String methodName,
String body, boolean isStatic) {
StringBuilder monitoredBody = new StringBuilder();
monitoredBody.append("{");
monitoredBody.append("long startTime = System.nanoTime();");
monitoredBody.append("try {");
monitoredBody.append("super." + methodName + "();");
monitoredBody.append("} finally {");
monitoredBody.append("long endTime = System.nanoTime();");
monitoredBody.append("long duration = endTime - startTime;");
monitoredBody.append("System.out.println(\"[监控] " + methodName +
" 耗时: \" + duration/1000000.0 + \"ms\");");
monitoredBody.append("if (duration > 50000000) {");
monitoredBody.append("System.out.println(\"[警告] " + methodName +
" 执行时间过长!\");");
monitoredBody.append("}");
monitoredBody.append("}");
monitoredBody.append("}");
return monitoredBody.toString();
}
// 更综合的示例
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
// 创建一个包含业务逻辑的类
CtClass ctClass = pool.makeClass("MonitoredBusiness");
ctClass.addMethod(CtMethod.make(
"public void process() {" +
"System.out.println(\"执行业务逻辑...\");" +
"try { Thread.sleep(1000); } catch(Exception e) {}" +
"}", ctClass));
// 转换为实际类
ctClass.toClass();
// 动态添加监控
monitorMethod("MonitoredBusiness", "process");
// 测试
Class<?> clazzClass = Class.forName("MonitoredBusiness");
Object instance = clazzClass.getDeclaredConstructor().newInstance();
Method method = clazzClass.getMethod("process");
method.invoke(instance);
}
}
注解驱动开发案例
import javassist.*;
import javassist.bytecode.*;
import java.lang.annotation.*;
// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface NeedChange {
String describe() default "default change";
boolean needChange() default true;
}
// 动态注解处理
public class AnnotationExample {
public static class MyClass {
@NeedChange(describe = "无参数方法")
public void methodA() {
System.out.println("原始方法A");
}
@NeedChange(describe = "带参数方法")
public String methodB(int x) {
return "结果: " + x;
}
public void noChange() {
System.out.println("未注解的方法");
}
}
public static void main(String[] args) throws Exception {
modifyAnnotatedMethods();
// 使用修改后的类
MyClass instance = new MyClass();
instance.methodA();
String result = instance.methodB(5);
System.out.println(result);
instance.noChange();
}
private static void modifyAnnotatedMethods() throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(MyClass.class.getName());
// 导出包结构
pool.insertClassPath(new ClassClassPath(MyClass.class));
// 遍历方法
for (CtMethod ctMethod : cc.getDeclaredMethods()) {
// 获取方法上的注解
MethodInfo methodInfo = ctMethod.getMethodInfo();
// 检查注解
AnnotationsAttribute attr = (AnnotationsAttribute)
methodInfo.getAttribute(AnnotationsAttribute.visibleTag);
if (attr != null) {
for (Annotation annotation : attr.getAnnotations()) {
if (annotation.getTypeName()
.contains("NeedChange")) {
// 调用getStringMember方法
String describe = annotation.getStringMember("describe");
// 动态生成代码
String newBody = generateModifiedBody(
ctMethod.getName(), describe);
// 修改方法体
ctMethod.setBody(newBody);
}
}
}
}
// 保存修改
cc.toClass();
}
private static String generateModifiedBody(String methodName,
String describe) {
StringBuilder body = new StringBuilder();
body.append("{");
body.append("System.out.println(\"[增强] " +
methodName + " - " + describe + "\");");
// 根据方法名智能生成代码
if (methodName.equals("methodA")) {
body.append("System.out.println(\"增强后的方法A执行\");");
} else if (methodName.equals("methodB")) {
body.append("return \"[增强]结果: \" + ($1 * 2);");
}
body.append("}");
return body.toString();
}
}
这些案例展示了Javassist在以下场景的强大应用:
- 动态代码生成:创建新类、修改现有类
- AOP实现:方法级拦截、日志记录、性能监控
- 代理实现:比JDK动态代理更高效的代理方案
- 缓存框架:自动方法缓存、键值缓存
- 注解处理:运行时注解驱动的代码修改
注意事项:
- 性能优化:合理使用ClassPool缓存
- 安全性:正确处理类加载器
- 调试:生成的字节码可能难以调试
- 版本兼容:不同JVM版本可能需要调整
这些案例可以直接用于生产环境的框架开发、中间件构建或性能优化场景。