javassist AOP
对于AOP,这个概念,不用解释,主要用途很多,我这里主要是为了后续研究如何实现APM做准备。前面研究了动态代理实现AOP,考虑到性能的问题,改用javassist直接修改直接码实现!
javassist的使用,可以参考官网, 在用eclipse开发程序的时候,要将这个javassist的jar包放入classpath下。若基于maven开发的话,也有对应的maven插件,很简单的事情!
下面主要列举一下常用的类以及方法:
获取JVM中已经加载的所有的类的集合,即pool
ClassPool pool = ClassPool.getDefault(); 获取指定类名对应的类
CtClass cc = pool.get("带有包名的全路径类名"); 为这个类设置超级类
cc.setSuperclass(pool.get("指定带有全路径的类名"));
另外还有CtMethod,CtField等等,这些可以到官网找相关的API文档了解其使用方法。下面通过一个简单的例子看看如何使用javassist来动态编写程序,实现AOP。
先定义一个业务类Feed.java,其中的函数,就好比是我们业务系统中的某个操作。
package javassit_aop; /**
*
* @author shihuc
* @date Mar 24, 2016
*
*/
public class Feed {
public void forTest(){
System.out.println("----------execute function \"forTest()\"-----------");
}
}
接下来,定义一个测试类,在这个测试类里面,通过javassist的函数调用,实现切面织入,也就是AOP的目的所在。这个类TEST.java:
package javassit_aop; import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException; /**
*
* @author shihuc
* @date Mar 24, 2016
*
*/
public class TEST {
public static void main(String[] args) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException{
CtClass ctClass=ClassPool.getDefault().get("javassit_aop.Feed");
String oldName="forTest";
CtMethod ctMethod=ctClass.getDeclaredMethod(oldName);
String newName=oldName+"$NewImpl";
ctMethod.setName(newName);
CtMethod newMethod=CtNewMethod.copy(ctMethod, "forTest", ctClass, null);
StringBuffer sb=new StringBuffer(); /*
* Here, below StringBuffer is to create the new method body, what you read is the source code,
* but, it will be translated to byte code which can be interpreted by JVM.
*
* To some extent, ".append(newName+"($$);\n")" can be said as function call to the business function Feed.forTest()
*/
sb.append("{System.out.println(\"Here you can do BEFORE operation\");\n")
.append(newName+"($$);\n")
.append("System.out.println(\"Here you can do AFTER operation\");\n}");
newMethod.setBody(sb.toString());
/*
* Add new method
*/
ctClass.addMethod(newMethod);
/*
* Class changed, ATTENTION, do not use "A a = new A();" to make a new instance,
* because in the same classloader it do not allow to load one class more than once.
*/
Feed a=(Feed)ctClass.toClass().newInstance();
a.forTest();
}
}
上面的代码执行完后,可以看到下面的结果:
Here you can do BEFORE operation
----------execute function "forTest()"-----------
Here you can do AFTER operation
上述代码中$$表示所有的参数,关于javassist的函数调用中参数传递,可以参考官网的说明,这里截取一部分,可以先有个概念,这个和shell脚本中的function调用是参数传递非常像!
The String object passed to the methods insertBefore(), insertAfter(), addCatch(), and insertAt() are compiled by the compiler included in Javassist. Since the compiler supports language extensions, several identifiers starting with $ have special meaning:
$0, $1, $2, ... this and actual parameters
$args An array of parameters. The type of $args is Object[].
$$ All actual parameters.
For example, m($$) is equivalent to m($1,$2,...)
$cflow(...) cflow variable
$r The result type. It is used in a cast expression.
$w The wrapper type. It is used in a cast expression.
$_ The resulting value
$sig An array of java.lang.Class objects representing the formal parameter types.
$type A java.lang.Class object representing the formal result type.
$class A java.lang.Class object representing the class currently edited.
虽然javassist的使用中也涉及到了反射的使用,大家都应该意识到,在产品级的软件中,若大量使用反射,性能是不会好的,当然javassist的官方组织也知道这点,所以,在使用的时候,可以通过定义interface,然后在javassist中动态编程来实现这个接口中的方法,调用方,通过这个接口来调用方法,这样就可以绕开因为反射造成的性能损失。
另外,javassist的深入灵活的使用,后续再继续研究,并及时更新博客!
javassist AOP的更多相关文章
- AOP的实现原理
1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. 类别 ...
- Javassist 通用工具之 CodeInjector
Javassist 通用工具之CodeInjector 最近在做一个APM项目,要在运行时代码修改.目前常用修改的几种工具有:ASM.BCEL.Javassist.经过对比,项目中采用了Javassi ...
- AOP详解
什么是AOP AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) Spring ...
- AOP的实现机制--转
原文地址:http://www.iteye.com/topic/1116696 1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前 ...
- Java动态编程初探——Javassist
最近需要通过配置生成代码,减少重复编码和维护成本.用到了一些动态的特性,和大家分享下心得. 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不 ...
- AOP的实现机制
1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. 类别 ...
- Spring AOP 动态代理 缓存
Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...
- AOP理解
1.问题 问题:想要添加日志记录.性能监控.安全监测 2.最初解决方案 2.1.最初解决方案 缺点:太多重复代码,且紧耦合 2.2.抽象类进行共性设计,子类进行个性设计,此处不讲解,缺点一荣俱荣,一损 ...
- spring aop开发常见错误
1. Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreExcepti ...
随机推荐
- Tranparent/cutout/diffuse
Shader "Tranparent/cutout/diffuse" { Properties { // _Color ("Main Color", Co ...
- lua元表和元方法 《lua程序设计》 13章 读书笔记
lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...
- SQL中使用WITH AS提高性能-使用公用表表达式(CTE)简化嵌套SQL
转:http://wudataoge.blog.163.com/blog/static/80073886200961652022389/ 一.WITH AS的含义 WITH AS短语,也叫做子 ...
- invoke Javascript from C# code
http://justyouraveragegeek.com/blog/index.php/2010/03/winforms-with-a-webbrowsercontrol-fun-with-obj ...
- LeetCode Sort Colors (技巧)
题意: 一个数组只可能含有3种数据,分别为1,2,3,请将数组排序(只能扫一遍). 思路: 如果扫两遍的话,用个桶记录一下,再赋值上去就行了. class Solution { public: voi ...
- SFTP 上传文件夹
使用sftp上传文件夹时若使用如下命令并不work: put /media/Research/GWAS_Class/* Desktop/ 此时,需要添加一个参数 -r, 另外在目标文件夹下面建立一个同 ...
- Lumia刷机Win10 Mobile 10.0.10166惊魂记
1 手贱,不愿等正式版正式发布,结果手动更新了,为此还熬了两个晚上. 2 第一次撞上去,没有无线了,倒.一开始还以为是预览版BUG,后来查了下重置就可以了,可以没有3G,没有WIFI也没办法备份,干, ...
- Spring MVC数组绑定
需求:商品批量删除,用户在页面选择多个商品,批量删除. 关键:将页面选择(多选)的商品id,传到controller方法的形参,方法形参使用数组接收页面请求的多个商品id // 批量删除 商品信息 @ ...
- 三国游戏 2010年NOIP全国联赛普及组
题目描述 Description 小涵很喜欢电脑游戏,这些天他正在玩一个叫做<三国>的游戏. 在游戏中,小涵和计算机各执一方,组建各自的军队进行对战.游戏中共有N 位武将(N 为偶数且不小 ...
- SVN代码提交冲突解决方案
SVN代码提交冲突解决方案 1.若你的代码被其他人修改并提交过了,期间你自己也修改过该文件,UPDATE的时候自己代码被覆盖. 右键——>显示日志 查看该文件的更新记录 找到需恢复的版本 右键— ...