对于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的更多相关文章

  1. AOP的实现原理

    1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. 类别 ...

  2. Javassist 通用工具之 CodeInjector

    Javassist 通用工具之CodeInjector 最近在做一个APM项目,要在运行时代码修改.目前常用修改的几种工具有:ASM.BCEL.Javassist.经过对比,项目中采用了Javassi ...

  3. AOP详解

    什么是AOP AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) Spring ...

  4. AOP的实现机制--转

    原文地址:http://www.iteye.com/topic/1116696 1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前 ...

  5. Java动态编程初探——Javassist

    最近需要通过配置生成代码,减少重复编码和维护成本.用到了一些动态的特性,和大家分享下心得. 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不 ...

  6. AOP的实现机制

    1 AOP各种的实现 AOP就是面向切面编程,我们可以从几个层面来实现AOP. 在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较. 类别 ...

  7. Spring AOP 动态代理 缓存

    Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...

  8. AOP理解

    1.问题 问题:想要添加日志记录.性能监控.安全监测 2.最初解决方案 2.1.最初解决方案 缺点:太多重复代码,且紧耦合 2.2.抽象类进行共性设计,子类进行个性设计,此处不讲解,缺点一荣俱荣,一损 ...

  9. spring aop开发常见错误

    1. Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreExcepti ...

随机推荐

  1. LeetCode Subsets (DFS)

    题意: 给一个集合,有n个互不相同的元素,求出所有的子集(包括空集,但是不能重复). 思路: DFS方法:由于集合中的元素是不可能出现相同的,所以不用解决相同的元素而导致重复统计. class Sol ...

  2. LeetCode Search a 2D Matrix II (技巧)

    题意: 有一个矩阵,每行有序,每列也有序.判断一个数target是否存在于此矩阵中. 思路: 从右上角开始,如果当前数字<target,则该行作废.若当前数字>target,该列作废.这样 ...

  3. 【ajax】xhr

    jQuery xhr: function() { return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP&quo ...

  4. supervisor很赞!

    最近,公司进行了新的架构设计,原来一个区服一组进程,变成了对外只有一台服,后面N组多进程进行服务的模式.于是,管理进程就变成了一个头痛的问题.原来是在写代码的目录里放置各种脚本解决的,关闭脚本,开启脚 ...

  5. 使用容器控制器控制另外两个控制器的view交换

    建三个UIViewController 的子控制器,其中一个为根控制器,另外两个控制器的视图作为切换对象 AppDelegate中代码 //AppDelegate.h中代码 #import <U ...

  6. POJ 3264 区间最大最小值Sparse_Table算法

    题目链接:http://poj.org/problem?id=3264 Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total ...

  7. webrtc编译之libcommonaudio

    [170/1600] CXX obj/webrtc/common_audio/common_audio.audio_util.o[171/1600] CXX obj/webrtc/common_aud ...

  8. mysql 关联删除

    参考网址:http://www.111cn.net/database/mysql/51146.htm 原网页广告太多,自己抄了下. 1.delete from t1 where 条件2.delete ...

  9. 所学新知——int、char型转string 类型等

    1. 利用stringstream类 定义头文件#include<sstream> 通过 int a; char b; sstream ss,ss1; ss<<a; ss1&l ...

  10. 某种数列问题 (jx.cpp/c/pas) 1000MS 256MB

    众所周知,chenzeyu97有无数的妹子(阿掉!>_<),而且他还有很多恶趣味的问题,继上次纠结于一排妹子的排法以后,今天他有非(chi)常(bao)认(cheng)真(zhe)去研究一 ...