对于AOP,这个概念,不用解释,主要用途很多,我这里主要是为了后续研究如何实现APM做准备。前面研究了动态代理实现AOP,考虑到性能的问题,改用javassist直接修改直接码实现!

javassist的使用,可以参考官网, 在用eclipse开发程序的时候,要将这个javassist的jar包放入classpath下。若基于maven开发的话,也有对应的maven插件,很简单的事情!

下面主要列举一下常用的类以及方法:

  1. 获取JVM中已经加载的所有的类的集合,即pool
  2. ClassPool pool = ClassPool.getDefault();
  3.  
  4. 获取指定类名对应的类
  5. CtClass cc = pool.get("带有包名的全路径类名");
  6.  
  7. 为这个类设置超级类
  8. cc.setSuperclass(pool.get("指定带有全路径的类名"));

另外还有CtMethod,CtField等等,这些可以到官网找相关的API文档了解其使用方法。下面通过一个简单的例子看看如何使用javassist来动态编写程序,实现AOP。

先定义一个业务类Feed.java,其中的函数,就好比是我们业务系统中的某个操作。

  1. package javassit_aop;
  2.  
  3. /**
  4. *
  5. * @author shihuc
  6. * @date Mar 24, 2016
  7. *
  8. */
  9. public class Feed {
  10. public void forTest(){
  11. System.out.println("----------execute function \"forTest()\"-----------");
  12. }
  13. }

接下来,定义一个测试类,在这个测试类里面,通过javassist的函数调用,实现切面织入,也就是AOP的目的所在。这个类TEST.java:

  1. package javassit_aop;
  2.  
  3. import javassist.CannotCompileException;
  4. import javassist.ClassPool;
  5. import javassist.CtClass;
  6. import javassist.CtMethod;
  7. import javassist.CtNewMethod;
  8. import javassist.NotFoundException;
  9.  
  10. /**
  11. *
  12. * @author shihuc
  13. * @date Mar 24, 2016
  14. *
  15. */
  16. public class TEST {
  17. public static void main(String[] args) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException{
  18. CtClass ctClass=ClassPool.getDefault().get("javassit_aop.Feed");
  19. String oldName="forTest";
  20. CtMethod ctMethod=ctClass.getDeclaredMethod(oldName);
  21. String newName=oldName+"$NewImpl";
  22. ctMethod.setName(newName);
  23. CtMethod newMethod=CtNewMethod.copy(ctMethod, "forTest", ctClass, null);
  24. StringBuffer sb=new StringBuffer();
  25.  
  26. /*
  27. * Here, below StringBuffer is to create the new method body, what you read is the source code,
  28. * but, it will be translated to byte code which can be interpreted by JVM.
  29. *
  30. * To some extent, ".append(newName+"($$);\n")" can be said as function call to the business function Feed.forTest()
  31. */
  32. sb.append("{System.out.println(\"Here you can do BEFORE operation\");\n")
  33. .append(newName+"($$);\n")
  34. .append("System.out.println(\"Here you can do AFTER operation\");\n}");
  35. newMethod.setBody(sb.toString());
  36. /*
  37. * Add new method
  38. */
  39. ctClass.addMethod(newMethod);
  40. /*
  41. * Class changed, ATTENTION, do not use "A a = new A();" to make a new instance,
  42. * because in the same classloader it do not allow to load one class more than once.
  43. */
  44. Feed a=(Feed)ctClass.toClass().newInstance();
  45. a.forTest();
  46. }
  47. }

上面的代码执行完后,可以看到下面的结果:

  1. Here you can do BEFORE operation
  2. ----------execute function "forTest()"-----------
  3. Here you can do AFTER operation

上述代码中$$表示所有的参数,关于javassist的函数调用中参数传递,可以参考官网的说明,这里截取一部分,可以先有个概念,这个和shell脚本中的function调用是参数传递非常像!

  1. 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:
  2.  
  3. $0, $1, $2, ... this and actual parameters
  4. $args An array of parameters. The type of $args is Object[].
  5. $$ All actual parameters.
  6. For example, m($$) is equivalent to m($1,$2,...)
  7.  
  8. $cflow(...) cflow variable
  9. $r The result type. It is used in a cast expression.
  10. $w The wrapper type. It is used in a cast expression.
  11. $_ The resulting value
  12. $sig An array of java.lang.Class objects representing the formal parameter types.
  13. $type A java.lang.Class object representing the formal result type.
  14. $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. JDBC接口规范

    前言 JDBC(JavaDatabase Connectivity)表示Java查询引擎连接,由一组用Java编程语言编写的类和接口组成.JDBC为Java程序访问关系型查询引擎提供了编程接口,为查询 ...

  2. Windows服务弹出MessageBox对话框

    Windows服务弹出MessageBox对话框 自从Windows升级到Vista版本后,系统服务就不在允许弹出那些惨绝人寰的MessageBox了(至于为什么不让弹出,原理有点小复杂,我也不是很门 ...

  3. 推荐!Sublime Text 最佳插件列表

    本文由 伯乐在线 - 艾凌风 翻译,黄利民 校稿.英文出处:ipestov.com.欢迎加入翻译组. 本文收录了作者辛苦收集的Sublime Text最佳插件,很全. 最佳的Sublime Text ...

  4. R中NA和NaN的区别

    NA表示的是缺失数据,missing data NaN表示无意义的数据,Not a Number, Inf-Inf Inf表示正无穷大 -Inf表示负无穷大

  5. iOS学习笔记---oc语言第三天

    继承.初始化方法 一.继承 继承的上层:父类  继承的下层:子类 继承是单向的,不能相互继承 继承具有传递性:A继承于B,B继承于C,A具有B和C的特征和行为 子类能继承父类全部的特征和行为(私有变量 ...

  6. ajax 城市区域选择三级联动

    <body onLoad="sheng()"><div class="xqbody">    <form action=" ...

  7. Letter Combinations of a Phone Number

    Given a digit string, return all possible letter combinations that the number could represent. A map ...

  8. UpdatePanel与$.function()同时使用问题

    在.NET中使用了UpdatePanel,里面的输入框使用了jQuery的日历选择器,接下来介绍下两者同时使用的一些细节及问题的解决方法,感兴趣的各位可以参考下哈 今天,在.NET中使用了Update ...

  9. leetcode 148. Sort List ----- java

    Sort a linked list in O(n log n) time using constant space complexity. 排序,要求是O(nlog(n))的时间复杂度和常数的空间复 ...

  10. android中ListView_SimpleAdapter

    1.首先看下main_activity.xml.其实里面就放了一个ListView. <LinearLayout xmlns:android="http://schemas.andro ...