javassist学习
最近学习了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学习的更多相关文章
- Javassist学习总结
今天在弄dubbo时出现了一个依赖缺少问题,就好奇研究一下,这个依赖是啥. javassist是一个字节码类库,可以用他来动态生成类,动态修改类等等 1.介绍Javassist 要想将编译时不存在的类 ...
- Java学习之javassist
1.读取和输出字节码 ClassPool pool = ClassPool.getDefault(); //会从classpath中查询该类 CtClass cc = pool.get("t ...
- 8.5(java学习笔记)8.5 字节码操作(javassist)
一.javassist javassist让我们操作字节码更加简单,它是一个类库,允许我们修改字节码.它允许java程序动态的创建.修改类. javassist提供了两个层次的API,基于源码级别的和 ...
- java 学习之路
一.基础篇 1.1 JVM 1.1.1. Java内存模型,Java内存管理,Java堆和栈,垃圾回收 http://www.jcp.org/en/jsr/detail?id=133 http://i ...
- Java 编程的动态性,第 6 部分: 利用 Javassist 进行面向方面的更改--转载
本系列的 第 4 部分和 第 5 部分讨论了如何用 Javassist 对二进制类进行局部更改.这次您将学习以一种更强大的方式使用该框架,从而充分利用 Javassist 对在字节码中查找所有特定方法 ...
- Java数据持久层框架 MyBatis之API学习四(xml配置文件详解)
摘录网址: http://blog.csdn.net/u010107350/article/details/51292500 对于MyBatis的学习而言,最好去MyBatis的官方文档:http:/ ...
- JAVAEE——BOS物流项目01:学习计划、搭建环境、主页设计(jQuery EasyUI)
1 学习计划 1.项目概述 项目背景介绍 2.搭建项目开发环境 数据库环境 maven项目搭建 svn环境搭建 3.主页设计(jQuery EasyUI) layout页面布局 accordion折叠 ...
- MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射
在上一章中我们学习了<MyBatis学习总结(一)——ORM概要与MyBatis快速起步>,这一章主要是介绍MyBatis核心配置文件.使用接口+XML实现完整数据访问.输入参数映射与输出 ...
- 我是怎样使用javassist将代码注入到帝国OL并进行调试的
帝国OL是拉阔一款手机网络游戏(腾讯也有代理),我在中学时代玩儿过. 帝国OL还维护着KJava版本游戏客户端,这意味着我们可以在PC端使用模拟器玩儿游戏. 不过这篇文章我主要是关注如何通过代码注入拦 ...
随机推荐
- UNITY中有Timer
using UnityEngine; using System.Collections; using System.Timers; public class NewBehaviourScript : ...
- [udemy]WebDevelopment_CSS
Your First CSS(Cascading Style Sheets) Cascading means it always takes selector that is at the end 即 ...
- ESXi系统命令行下启动虚拟机
从命令行启动虚拟机: 用命令列出虚拟机的ID:vim-cmd vmsvc/getallvms |grep <vm name>注意: 第一列输出是vmid. 用命令查看虚拟机启动状态:vim ...
- [Selenium] 针对下拉菜单出现之后又立马消失的问题,通过Javascript改变元素的可见属性
public void clickDateDropDownButton() { SeleniumUtil.jsClick(driver, page.getDateDropdownButtonOfInv ...
- An interview question from MicroStrategy
去年校招时的一道面试题,觉得蛮有意思,贴出来. Question: Spy start at a, during an interval he moves |b| to right when b &g ...
- 详解jQuery的$符号和init函数
本文所有代码,出自jQuery.1.5.2,为方便理解,引入类的概念,虽然jQuery不是基于面向对象思想. jQuery是现在最流行的JavaScript框架, $是其中最常见的符号,已经在jQue ...
- IRC聊天指南
参考https://www.cnblogs.com/fzzl/archive/2011/12/26/2302637.html
- 一条java开发工程师的升级路线,从初级到无语言障碍
看了一篇文章,讲述的是如何进行后端开发升级,现在分享下,我的总结,感谢写文章的作者大大,觉得他很会坚持,虽然一直在骂人,但是,我觉得人最大的敌人就是懒惰,所以骂得好 现在写下我的总结,希望对有志者有帮 ...
- 一)get started with the Quartz project
官网 http://www.quartz-scheduler.org/ 下载链接 http://www.terracotta.org/download/reflector.jsp?b=tcdistri ...
- 第二届CCCC赛后感想 2017-04-15 23:56 88人阅读 评论(0) 收藏
第一次写赛后感想,也不算什么很正规的比赛,不过这次比赛的时间恰好处于思想变化的阶段,留贴纪念. 先谈谈这次比赛,弱校萌新,依靠申请进了总决赛,发现和第一届不一样,缺少了团队奖心中有点缺乏动力,比赛2个 ...