引言

众所周知,一旦提到AOP,相信大家都是条件反射的想到JDK代理和CGLib代理,没错,这两个代理都是在运行时内存中临时生成代理类,故而又称作运行时增强——动态代理。世间万物都不是绝对的,既然有动态代理,那么,是否有想过:是不是存在静态代理呢?

LTW(Load Time Weaving)

其实,除了运行时织入切面的方式外,我们还有一种途径进行切面织入,它可以在类加载期通过字节码转换,进而将目标织入切入点(目标类),这种方式就是LTW,即静态代理(静待代理也被称作编译时增强,后面会有相关代码样例)。

LTW在Java5的时候就被引入了,想要了解其原理,先要了解一个知识——Instrument包。

java.lang.instrument包的工作原理

JDK5.0时引入了此包,目的就是为了能对JVM底层组建进行访问。如何访问?其实说来个人觉得还挺麻烦的,就是需要通过JVM的启动参数-javaagent在启动时获取JVM内部组件的引用。参数格式如下:

-javaagent:[=options]

此处先卖个关子,不急着解释参数中的jarpath和options,后面的运行代码及结果的样例中会进行针对使用红框标记说明,效果更好。

那么,它和AOP有和关系呢?因为它在JVM启动时会装配并应用ClassTransformer,对类字节码进行转换,进而实现AOP的功能

下面说一下instrument包下的两个重要接口:

  • ClassFileTransformer

它是Class文件转换器接口,这个接口有且仅有一个方法,如图所示:

注意:transform方法会有一个返回值,类型是byte[],表示转换后的字节码,但是如果返回为空,则表示不进行节码转换处理,千万不要当作是把原先类的字节码清空。

  • Instrumentation

这个接口提供了很多方法,我们主要注意一个方法即可,即:addTransformer方法,它的作用就是把一些ClassFileTransformer注册到JVM内部,接口如图所示:

具体工作原理是这样的:

① ClassFileTransformer实例注册到JVM之后,JVM在加载Class文件时,就会先调用ClassFileTransformer的transform()方法进行字节码转换;

② 若注册了多个ClassFileTransformer实例,则按照注册时的顺序进行一次调用。

这样也就实现了从JVM层面截获字节码,进而织入操作者自己希望添加的逻辑,即实现AOP效果。

代码及演示效果

说了这么多,来点干货,下面用代码给大家演示一下如何向JVM中注册转换器实现AOP的。为了方便大家阅读,重要的说明笔者已经写在代码的注释上或者图片空白处,大家注意查看。

  • 首先,我们实现一个自己的转换器,用于模拟需要切入的功能

注意,这里再强调下,代码中的return null;并不是将加载类的字节码置空。

  • 其次,我们再实现一个代理类

为什么要实现代理类内,因为不是动态代理呀。。。

  • 最后,我们写一个主函数,代表程序入口

到此为止,我们的Demo算是完成了,先来看一下运行的结果:

打jar的时候需要注意的地方

大家看到执行结果的截图中,cmd界面下运行javaagent参数时指定了一个myTransformer.jar,这个jar是我们自己需要打出来的,可以直接使用eclipse具体步骤如下图所示,注意图中说明:

总结

大家可以看到,其实使用此类代理并没有动态代理方便,甚至转换器可能会对JVM所有类都产生影响,操作起来更新相对麻烦,实际生产部署时会有很多不便。

但是,写这些是为了让大家更好、更多的去了解AOP,我们所熟知的AOP其实还有很多东西有待我们自身去学习和发现,其实Spring在"操作麻烦"这方面还是做了不少事的,提供了一些xml的配置化管理(此处就不再说了,因为感觉一说又是一大长篇,有兴趣的大家可以自己去看看,多了解写东西总没有坏处),很多情况下已经不需要再配置javaagent参数了。

最后提一句,如果在面试中提到了这些,相信面试官也会有加分吧。

fedora 不在sudoers文件中_Spring AOP中还有你不知道的JVM Class文件字节码转换知识!...相关推荐

  1. 应用程序文件Android安全分析挑战:运行时篡改Dalvik字节码

    发一下牢骚和主题无关: 本文章由Jack_Jia编写,转载请注明出处. 文章接链:http://blog.csdn.net/jiazhijun/article/details/8833710 作者:J ...

  2. 在eclipse中安装properties插件PropertiesEditor及设置(附图),ASCII码转换成中文

    在eclipse中安装properties插件PropertiesEditor及设置(附图),ASCII码转换成中文 安装成功后ASCII还是不能转换成中文的,原因是设置里面没有把编码设置为utf8的 ...

  3. java args例子_Spring AOP中使用args表达式的方法示例

    本文实例讲述了Spring AOP中使用args表达式的方法.分享给大家供大家参考,具体如下: 一 配置 xmlns:xsi="http://www.w3.org/2001/XMLSchem ...

  4. java切点配置_Spring AOP中定义切点的实现方法示例

    本文实例讲述了Spring AOP中定义切点的实现方法.分享给大家供大家参考,具体如下: 一 配置 xmlns:xsi="http://www.w3.org/2001/XMLSchema-i ...

  5. java post 多文件报头_Spring MVC-------文件上传,单文件,多文件,文件下载

    Spring MVC框架的文件上传是基于 commons-fileupload 组件的文件上传,只不过SpringMVC 框架在原有文件上传组件上做了进一步封装,简化了文件上传的代码实现,取消了不同上 ...

  6. bat 调用class文件_拯救写框架的程序员!用字节码替代反射,实现任意函数调用...

    作者 | 阿里巴巴文娱高级开发工程师 兰摧 技术类别:JAVA,后端技术,中间件开发,框架开发 技术亮点:字节码实现类似反射的功能,速度接近JAVA原生的调用 一.背景 我们在写一些框架或者中间件时, ...

  7. JVM之Java字节码(.class)文件详解

    前言 我们在使用IDEA工具编写java代码时,当执行程序时,IDEA会使用JDK帮我们执行编译命令,在target目录下生成对应的.class文件,为了加深对.class文件的理解.写了这篇文章,加 ...

  8. java 前置通知_spring aop中的前置通知

    fixassetService myInterceptor myInterceptor2 在上面的配置文件中 我配置了两个interceptor ,这两个interceptor的invoke方法中的逻 ...

  9. jpa怎么传参到in中_Spring Boot中的测试

    简介 本篇文章我们将会探讨一下怎么在SpringBoot使用测试,Spring Boot有专门的spring-boot-starter-test,通过使用它可以很方便的在Spring Boot进行测试 ...

最新文章

  1. 景观专业结合计算机基础的论文,计算机基础应用论文
  2. Effective C++ 条款05
  3. C++ Primer 5th笔记(chap 17 标准库特殊设施)ECMAScript正则表达式
  4. b350主板支持cpu列表_惊!AMD旧主板通过这个方法竟也能支持PCIe4.0
  5. mysql timestamp 类型_MySQL中“诡异”的TIMESTAMP数据类型
  6. IBM收购以色列应用发现公司EZSource
  7. 记一次神奇的SQL查询经历,group by慢查询优化
  8. Java基础学习总结(148)——如何提高代码质量
  9. UVALive - 6440(模拟)
  10. UG NX 12 草图尺寸小数点怎么更改?
  11. surfacert能跑java么_不怕天气糟糕 出行全靠Surface来帮忙
  12. Nginx配置https及证书
  13. 【区块链】以太坊Solidity编程:智能合约实现之基本语法
  14. 计算机表格填充,Excel表格的自动填充功能
  15. linux perl环境搭建,Perl 环境安装
  16. 高德地图标识大全_连地震都查得一清二楚!高德地图新功能体验
  17. 20222817《Linux内核原理与分析》第五周作业
  18. 条码固定资产管理PDA应用
  19. java socket 打印机_思普瑞特,小票打印机和标签打印机java网络驱动设计与实现...
  20. 音视频技术开发周刊 79期

热门文章

  1. 算法分析:Oracle 11g 中基于哈希算法对唯一值数(NDV)的估算
  2. 时过境迁:Oracle跨平台迁移之XTTS方案与实践
  3. 【华为云技术分享】Linux内核编程环境 (2)
  4. RDS关系型数据库 入门 01 创建关系型数据库实例【华为云分享】
  5. 补习系列(21)-SpringBoot初始化之7招式
  6. Docker存储卷基本操作
  7. 设计模式笔记二十二:空对象模式
  8. pycharm不能输入代码或删除代码
  9. C++学习系列笔记(八)
  10. dll可以在linux下使用吗_Linux下使用rm删除文件,并排除指定文件