深入了解JVM字节码增强技术
作者:loytime 发布时间:2021-06-04 16:28:13
这篇文章主要介绍了深入了解JVM字节码增强技术,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
JVM——字节码增强技术简介
Java字节码增强指的是在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修改。Java字节码增强主要是为了减少冗余代码,提高性能等。
实现字节码增强的主要步骤为:
1、修改字节码
在内存中获取到原来的字节码,然后通过一些工具(如 ASM,Javaasist)来修改它的byte[]数组,得到一个新的byte数组。
2、使修改后的字节码生效
有两种方法:
1) 自定义ClassLoader来加载修改后的字节码;
2)替换掉原来的字节码:在JVM加载用户的Class时,拦截,返回修改后的字节码;或者在运行时,使用Instrumentation.redefineClasses方法来替换掉原来的字节码;
3. 两种实现机制:
(1) 通过创建原始类的一个子类(动态创建的类继承原来的类)。子类名以原始类名为前缀,以避免重名。Spring AOP 使用的就是这种
(2) 直接修改原始类的字节码。类的跟踪过程中使用
4. 实现字节码增强要执行两个步骤:
(1) 在内存中获取到原始的字节码, 然后通过一些开源的API 来修改它的byte[] 数组,得到一个新的byte[] 数组。
(2) 将新的byte[] 数组加载到PermGen 区(即加载新的byte[] 数组或替换原始类的字节码)。
接口 BCInterface
public interface BCInterface {
void enhancement();
}
实现类 BCEnhancement.java
public class BCEnhancement implements BCInterface{
public void enhancement() {
System.out.println("hello enhancement");
}
}LogProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogProxy implements InvocationHandler {
private Object object;
public Object getProxyObject(Object o){
object=o;
try{
return Proxy.newProxyInstance(this.getClass().getClassLoader(),o.getClass().getInterfaces(),this);
}catch (IllegalArgumentException e){
throw new RuntimeException(e);
}
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before invoke ...");
Object result= method.invoke(object,args);
System.out.println("after invoke ...");
return result;
}
}
测试类 Test.java
public class Test {
public static void main(String[] args) {
LogProxy logProxy = new LogProxy();
System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
BCInterface byteCodeEn = (BCInterface) logProxy.getProxyObject(new BCEnhancement());
byteCodeEn.enhancement();
}
}
输出:
before invoke ...
hello enhancement
after invoke ...
来源:https://www.cnblogs.com/loytime/p/11749979.html


猜你喜欢
- 前言:mybatisplus 可以说是对mybatis更好的拓展,一些简单的增删改查的操作已经被作者实现,我们只需引用即可。1.数据库建表这
- Mybatis Plus流式查询mybatis plus 中自定义如下接口,就可以实现流式查询,mybatis 中同样适用。@Select(
- 前言好久没有更新博客了,今天和大家分享一个关于emoji表情持久化问题,相信做web开发的都遇到过这样的问题,因为我们知道mysql的utf
- 1、添加一个App.config配置文件。2、配置服务http://Lenovo-PC:80/EvisaWS/WharfService?ws
- android在网络上下载文件,供大家参考,具体内容如下步骤: 1.使用HTTP协议下载文件- 创建一个HttpURLConnection对
- 应用场景最近社区总有人发文章带上小广告,严重影响社区氛围,好气!对于这种类型的用户,就该永久拉黑!社区的安全框架使用了 spring-sec
- 目录一、野指针二、悬空指针2.1 情况一2.2 情况二2.3 情况三野指针和悬空指针是指针中常见的两个概念,本文结合实例讲解来讲解下。一、野
- 最近一个项目中,需要用到Java的websocket新特性,于是就学了一下,感觉这技术还挺好玩的,瞬间知道网页上面的那些在线客服是怎么做的了
- 在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择。这些功能我们叫它Android Di
- 前言通过前面的博客我们已经大致了解了关于Java的基本知识,而下面的几篇博客我们着重开始对于数据结构的知识进行学习,这篇博客我们就了解关于顺
- 一、概述Groovy is a multi-faceted language for the Java platform.Apache Gr
- 最近项目里有用到ViewPager来做广告运营位展示,看到现在很多APP的广告运营位都是无限循环的,所以就研究了一下这个功能的实现。先看看效
- java 中编写 GUI 有两中工具包,分别为 AWT、Swing。Swing 是 AWT 的拓展,Swing 具有比 AWT 丰富的组件和
- 宏定义与预处理命令预处理阶段:处理宏定义与预处理命令;编译期:检查代码,分析语法、语义等,最后生成.o或.obj文件;链接期:链接所有的.o
- 一种可以设置滑动动画的控件,只显示一行布局,在布局文件中的ViewFlipper控件中顺序写好每一行的布局(1).MainActivity.
- 一、国际化准备资源文件,资源文件的命名格式如下:baseName_language_country.propertiesbaseName_l
- 废话不多说,直接上代码/// <summary> /// 获得当前绝对路径
- 本文实例讲述了C#自定义针对URL地址的处理类。分享给大家供大家参考。具体分析如下:这个C#类是专门针对URL网址处理的类,可以对URL地址
- 1.相关概念Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。建
- 很多开发者表示,不知道Android的Drawable和Bitmap之间如何相关转换。下面Android123给大家两种比较简单高效的方法。