最近学习了javassist的使用方法。
javassist是一个字节码类库,可以用他来动态生成类,动态修改类等等。
下面是如果用javassist来动态创建一个类的demol
我们需要创建的目标类,如下:
public class JavassistClass{
private String name="default";
public JavassistClass(){
name="me";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void execute(){
System.out.println(name);
System.out.println("execute ok");
}
}
如下为用javassist来创建类的代码:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtField.Initializer;
import javassist.CtMethod;
import javassist.CtNewMethod;
public class JavassistLearn{
public static void main(String[] args) throws Exception{
ClassPool cp=ClassPool.getDefault();
CtClass ctClass=cp.makeClass("com.slovef.JavassistClass");
StringBuffer body=null;
//参数 1:属性类型 2:属性名称 3:所属类CtClass
CtField ctField=new CtField(cp.get("java.lang.String"), "name", ctClass);
ctField.setModifiers(Modifier.PRIVATE);
//设置name属性的get set方法
ctClass.addMethod(CtNewMethod.setter("setName", ctField));
ctClass.addMethod(CtNewMethod.getter("getName", ctField));
ctClass.addField(ctField, Initializer.constant("default"));
//参数 1:参数类型 2:所属类CtClass
CtConstructor ctConstructor=new CtConstructor(new CtClass[]{}, ctClass);
body=new StringBuffer();
body.append("{\n name=\"me\";\n}");
ctConstructor.setBody(body.toString());
ctClass.addConstructor(ctConstructor);
//参数: 1:返回类型 2:方法名称 3:传入参数类型 4:所属类CtClass
CtMethod ctMethod=new CtMethod(CtClass.voidType,"execute",new CtClass[]{},ctClass);
ctMethod.setModifiers(Modifier.PUBLIC);
body=new StringBuffer();
body.append("{\n System.out.println(name);");
body.append("\n System.out.println(\"execute ok\");");
body.append("\n return ;");
body.append("\n}");
ctMethod.setBody(body.toString());
ctClass.addMethod(ctMethod);
Class<?> c=ctClass.toClass();
Object o=c.newInstance();
Method method=o.getClass().getMethod("execute", new Class[]{});
//调用字节码生成类的execute方法
method.invoke(o, new Object[]{});
}
}
javassist还有一个比较常见的用途是AOP,比如对一些类统一加权限过滤,加日志监控等等。
下面示例如何使用javassist来进行AOP拦截处理
我们对上面例子的JavassistClass类的getName()方法进行拦截前置处理
package com.taobao.relationrecommend.web.util;
import java.lang.reflect.Method;
import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
public class JavassistLearn{
public static void main(String[] args) throws Exception{
ProxyFactory factory=new ProxyFactory();
//设置父类,ProxyFactory将会动态生成一个类,继承该父类
factory.setSuperclass(JavassistClass.class);
//设置过滤器,判断哪些方法调用需要被拦截
factory.setFilter(new MethodFilter() {
@Override
public boolean isHandled(Method m) {
if(m.getName().equals("getName")){
return true;
}
return false;
}
});
//设置拦截处理
factory.setHandler(new MethodHandler() {
@Override
public Object invoke(Object self, Method thisMethod, Method proceed,
Object[] args) throws Throwable {
//拦截后前置处理,改写name属性的内容
//实际情况可根据需求修改
JavassistClass o=(JavassistClass) self;
o.setName("haha");
return proceed.invoke(self, args);
}
});
Class<?> c=factory.createClass();
JavassistClass object=(JavassistClass) c.newInstance();
System.out.println(object.getName());
}
}
分享到:
相关推荐
Javassist学习手册,API,快速入门
javassist或许可以帮助到正在学习java的初学者,可以使用。
主要介绍了Javassist如何操作Java 字节码,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
主要介绍了javassist的使用方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
分析,编辑,创建java字节码的类库,可以供学习之用!
主要介绍了基于javassist进行动态编程过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
学习springmvc专用,包含 spring.jar、spring-webmvc.jar、commons-logging.jar、cglib-nodep-2.1_3.jar hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、antlr-2.7.6.jar、commons-collections-3.1、dom4...
入门Vue.js基础学习笔记记录,遇坑!
我们一起来学习hibernate吧 antlr-2.7.6.jar commons-collections-3.1.jar dom4j-1.6.1.jar hibernate3.jar javassist-3.11.0.GA.jar jta-1.1.jar slf4j-api-1.5.8.jar slf4j-nop-1.5.2.jar
查看: jd-gui源码jar包反编译工具:可以进行学习的源码jar查看; 修改jar源码: JByteMod-1.8.2(可以修改-不好用,不如360压缩打开后替换class); 建议采用javassist.jar
mybatis 学习记录 tip:要使用代码的话,请自己附加下面的jar包 asm-3.3.1.jar cglib-2.2.2.jar commons-logging-1.1.1.jar javassist-3.17.1-GA.jar log4j-1.2.17.jar log4j-api-2.0-rc1.jar log4j-core-2.0-rc1....
适合找不到成员工作的、计算机专业的、热爱Java的伙伴阅读
不幸的是在第一版,我还是依赖了 Javassist 可以很好的和各种主流框架和类库等协同工作 你可以组合 Nutz.Dao + Spring 你可以用 Nutz.Ioc 配合 Hibernate Nutz 的任何模块都是可以单独使用的 提供一条更低的且平滑的...
Java代理在之前的文章中主要学习了javassist和JavaAgent的使用;上一篇文章中主要是使用Javassist在JavaAgent中动态修改内容,但是只能写代码中,这里我们使用系统替代和数据库两种方式实现。一,系统数值:1.1,入...
java8 集合源码分析 1 介绍 1.1 用途 单元测试mock 联调、集成测试mock 支持mock静态方法,final方法,私有方法 非常容易实现spring bean的mock ...学习使用javassist增强字节码 了解dubbo消费端执
CodeGuide:本代码库是作者小傅哥多年从事一线互联网Java开发的学习历程技术总结,逐步为大家提供一个清晰详细的学习教程,侧重点更容易编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注,点赞,分享...
①JDK8 ②MyBatis3.4.7源码在别的项目中引用调试MyBatis源码(JDK8 +允许ognl / javassist传递依赖) java_mybatis ①JDK8 ②Java直接整合MyBatis在Java中直接使用MyBatis框架需要读取配置,手动构造...
本文档详细介绍了,如何使用JDK代理技术动态打印出入参及出参的类型、名字及值,值得大家学习和借鉴。