项目中有很多的界面对象描述类,他们都是接口View的实现,在输出的时候,需要按照特定格式输出成xml表现;
起初采用Commons beanutils的分析对象的方法,获取所有属性的值,构建格式输出;
如有以下的Class
class LabelView implements View {
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
有对应的类
LabelView label = new LabelView();
label.setId("label1");
label.setValue("Hello, world.");
前端需要的输出格式内容为
<label id="label1" value="Hello, world."></label>
另有以下的Class
class TextfieldView implements View {
private String id;
private String name;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
有对应的类
TextfieldView textfield = new TextfieldView();
textfield.setId("field1");
textfield.setName("field1");
textfield.setValue("张三");
前端需要的输出格式内容为
<textfield id="field1" name="field1" value="张三"></textfield>
实际使用的时候,由于存在众多的界面对象描述类需要解析,发现beanutils的时间效率比较低下;
后来考虑采用字节码操作工具对类进行改写,达到自动生成toString()方法的目的;比较了asm和javassist,发现asm的代码太复杂了,所以决定采用javassist;
对class的属性分析代码与beanutils的方式类似,只是需要新生成一个class而已;
过程是这样的:
[list]
通过javassist生成一个新的class,如LabelView,则生成LabelViewAccess extends LabelView
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(View.class));
CtClass ccOld = pool.get(className);
CtClass ccNew = pool.makeClass(className + "Access");
ccNew.setSuperclass(ccOld);
读取LabelView的结构,取得所有的get和is方法
CtMethod[] methods = ccOld.getMethods();
for (CtMethod method : methods) {
if (method.getName().startsWith("set")) {
String shortName = method.getName().substring(3);
String fieldName = shortName.toLowerCase();
if (method.getParameterTypes()[0].getName().equals(boolean.class.getName())) {
// is
} else {
// get
}
}
}
利用javassist构建toString()方法,将上面取得的方法进行字符串拼接
String n = ..; // TODO 取得className LabelView对应的输出名称label
StringBuffer strbuff = new StringBuffer();
strbuff.append("java.lang.StringBuffer sb = new java.lang.StringBuffer();");
strbuff.append("sb.append(\"<" + n + "\");");
// TODO 以下代码嵌入上面的循环内部
if (method.getParameterTypes()[0].getName().equals(boolean.class.getName())) {
strbuff.append("sb.append(\" " + fieldName + "=\\\"\"+is" + shortName + "()+\"\\\"\");");
} else {
strbuff.append("sb.append(\" " + fieldName + "=\\\"\"+get" + shortName + "()+\"\\\"\");");
}
strbuff.append("sb.append(\">\");");
strbuff.append("sb.append(\"</" + n + ">\");");
strbuff.append("return sb.toString();");
CtMethod sm = new CtMethod(pool.get("java.lang.String"), "toString", null, ccNew);
sm.setBody("{" + strbuff.toString() + "}");
ccNew.addMethod(sm);
调用javassist的CtClass.toClass()方法返回LabelView的真实class LabelViewAccess,并存储起来备用
Map<String, Class> classMap = new HashMap<String, Class>();
classMap.put(className, ccNew.toClass());
使用的时候,获得上面的LabelViewAccess,然后class.getConstructor().newInstance()获取带有格式化输出toString方法的LabelView对象
classMap.get(className).newInstance().toString();
[/list]
采用javassist之后,时间效率明显提高,基本上就等于手写的toString方法
分享到:
相关推荐
javassist, Java字节码工程工具包 Java字节码工程工具包 版本 3版权所有( C ) 1999 -2017按 Shigeru Chiba,保留所有权利。Javassist ( Java编程助手) 使Java字节码操作简单。 它是一个类库,用于在Java中编辑字节码
借助jclasslib与javassist修改java class字节码.doc
javassist+javaAgent探针, 实现jvm退出时打印线程栈日志,方便排查是哪个线程调用了退出,以及退出码
环境JDK1.8 IDEA项目 javaagent+javassist 下载后导入即可
JavaAgent Javassist 与 Asm JavaAgent 字节码动态编程项目
使用javassist修改class文件.pdf
Javassist 提供了java类库,用于方便操控Java字节码。功能包括:运行时创建java class,修改class。与其他同类工具(asm等)不同的是,Javassist提供了两个层面的API: 1.java代码层 2.字节码层 通过java代码层,...
赠送jar包:javassist-3.19.0-GA.jar;...使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
赠送jar包:javassist-3.23.1-GA.jar;...使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
Java字节码工程工具包
Javassist(JAVA编程ASSISTant)使Java字节码操作变得简单。 它是一个用Java编辑字节码的类库。 它使Java程序可以在运行时定义新类,并在JVM加载它时修改类文件。 与其他类似的字节码编辑器不同,Javassist提供了两...
能够实现java包的重写,分析,java程序的利器,不会的可以网上搜索相关使用方法,也可以留言求助。内含java包及demo,使用时直接引用java包即可。
赠送jar包:javassist-3.24.0-GA.jar;...使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
Javassist (Java Programming Assistant) makes Java bytecode manipulation simple. It is a class library for editing bytecodes in Java; it enables Java programs to define a new class at runtime and to ...
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 双语对照,边学技术、边学英语。
Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作...
赠送jar包:javassist-3.21.0-GA.jar;...使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。