当前位置:首页 > 开发 > 系统架构 > 架构 > 正文

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

发表于: 2013-11-16   作者:alleni123   来源:转载   浏览次数:
摘要: package com.lj.javassist; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Example01 { public static void main(String[] args) throws Exception
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那段,
The default value of ClassPool.doPruning is false.

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


因此只要把这段代码放在
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查询方法的代理,和延迟加载。
具体内容以后再慢慢研究了。

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
说起aop,大家都很熟悉。 ①.Aop是什么呢? 通常来讲就是Aspect Oriented Programming的缩写,翻译
由于本猿本次的目的只有单例生命周期的对象们。 写一个装配仪,遍历原始类型所有声明字段,查看字段
1.编辑器的入门使用 去http://ueditor.baidu.com下载 选择自己需要的字符集类型,下载本地表情 然后
需要源码的同学请留言! activiti是JBPM4的后续产品,因为没有用过JBPM4,所以开始对这个产品摸不着
一、介绍: Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用
4 LED Button 应用实例 LED Button 应用示例是为了让你学习如何在nRF51822上开发BLE应用,它是一个
c/s控制台应用程序,Server、Client分别在两个项目中 服务端 using System; using System.Collectio
第一步 新建一个webservice interface(注意加入注解包) import javax.jws.WebService; @WebServic
From: http://user.qzone.qq.com/339751607 1> 获取axis及关联的jar包 http://dl.iteye.com/topi
HelloWorld.java package use.basic; import java.io.IOException; import java.io.Reader; import
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号