Javassist简单入门实例 - 修改Class并写入磁盘

package com.lj.javassist;

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

public class Example01
{
public static void main(String[] args) throws Exception
{
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.lj.javassist.User");


//byte[] b=cc.toBytecode();




CtMethod[] cms=cc.getDeclaredMethods();

for(CtMethod cm:cms){
cm.insertAfter("System.out.println(\"hello : \"+this.name);");
}

Class clz=cc.toClass();
User u=(User) clz.getConstructor(new Class[]{}).newInstance(new Object[]{});

u.setName("alleni");

System.out.println(u.getName());



// cc.writeFile();
}
}



这个代码的运行结果是:
hello : alleni
hello : alleni
alleni

这里不能执行cc.writeFile(), 否则会报错:
com.lj.javassist.User was pruned.

看了一下官方文档, 貌似要加入
cc.stopPruning(true);
这段文档在Frozen class那段,
[color=blue]The default value of ClassPool.doPruning is false.

To disallow pruning a particular CtClass, stopPruning() must be called on that object in advance:[/color]

因此只要把这段代码放在
ClassPool pool=ClassPool.getDefault();
CtClass cc=pool.get("com.lj.javassist.User");


//byte[] b=cc.toBytecode();


cc.stopPruning(true);


再次运行, 一切正常。


用FrontEnd反编译class文件, 可以看到如下代码


// Decompiled Using: FrontEnd Plus v2.03 and the JAD Engine
// Available From: http://www.reflections.ath.cx
// Decompiler options: packimports(3)
// Source File Name: User.java

package com.lj.javassist;

import java.io.PrintStream;

public class User
{

public User()
{
}

public int getId()
{
_L2:
return i;
int i = id;
System.out.println("hello : " + name);
if(true) goto _L2; else goto _L1
_L1:
}

public void setId(int id)
{
_L2:
return;
this.id = id;
Object obj = null;
System.out.println("hello : " + name);
if(true) goto _L2; else goto _L1
_L1:
}

public String getName()
{
_L2:
return s;
String s = name;
System.out.println("hello : " + name);
if(true) goto _L2; else goto _L1
_L1:
}

public void setName(String name)
{
_L2:
return;
this.name = name;
Object obj = null;
System.out.println("hello : " + this.name);
if(true) goto _L2; else goto _L1
_L1:
}

private int id;
private String name;
}


虽然不知道那些if else语句和obj=null是什么玩意儿, 不过目标功能是实现了。
所有的方法都被加入了这句System.out.println(xxx);

Hibernate里面用到了Javassist,并通过这个东西实现了load查询方法的代理,和延迟加载。
具体内容以后再慢慢研究了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值