欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?Agent探針技術(shù)詳解示例

 更新時間:2022年06月16日 08:46:36   作者:hi?wei  
這篇文章主要介紹了Java?Agent?探針技術(shù)詳情,Java?中的?Agent?技術(shù)可以讓我們無侵入性的去進行代理,最常用于程序調(diào)試、熱部署、性能診斷分析等場景,下文更多相關(guān)資料,感興趣的小伙伴可以參考一下

什么是java agent?

在JVM中運行中,類是通過classLoader加載.class文件進行生成的。在類加載加載.class文件生成對應(yīng)的類對象之前時,我們可以通過修改.class文件內(nèi)容(就是字節(jié)碼修改技術(shù)),達到修改類的目的。JDK提供了對字節(jié)碼進行操作的一系列api,而使用這些api開發(fā)出的程序就可以稱之為java agent。

java agent能做什么?

不修改目標(biāo)應(yīng)用達到代碼增強的目的,就好像spring的aop一樣,但是java agent是直接修改字節(jié)碼,而不是通過創(chuàng)建代理類。例如skywalking就是使用java agent技術(shù),為目標(biāo)應(yīng)用代碼植入監(jiān)控代碼,監(jiān)控代碼進行數(shù)據(jù)統(tǒng)計上報的。這種方式實現(xiàn)了解耦,通用的功能。

文末附上了我寫的一款接口mock agent。感興趣的可以看看,學(xué)習(xí)一波。

使用示例

入門

創(chuàng)建maven工程

創(chuàng)建一個簡單的maven工程:

添加agent類:

package com.hiwei;
import java.lang.instrument.Instrumentation;
public class DemoAgent {
    /**
     * 該方法在main方法之前運行
     */
    public static void premain(String arg, Instrumentation instrumentation) {
        System.out.println("執(zhí)行premain方法");
    }
}

pom.xml打包配置

添加打包插件:

      <plugins>
        <plugin>
          <artifactId>maven-shade-plugin</artifactId>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
              <configuration>
                <shadedArtifactAttached>false</shadedArtifactAttached>
                <createDependencyReducedPom>true</createDependencyReducedPom>
                <createSourcesJar>true</createSourcesJar>
                <shadeSourcesContent>true</shadeSourcesContent>
                <transformers>
                  <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                    <manifestEntries>
                      <!-- 包含premain方法的類 -->
                      <Premain-Class>${premain.class}</Premain-Class>
                      <!-- 對目標(biāo)類字節(jié)碼操作權(quán)限 -->
                      <Can-Redefine-Classes>${can.redefine.classes}</Can-Redefine-Classes>
                      <!-- 對目標(biāo)類字節(jié)碼操作權(quán)限 -->
                      <Can-Retransform-Classes>${can.retransform.classes}</Can-Retransform-Classes>
                    </manifestEntries>
                  </transformer>
                </transformers>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>

將工程打成jar包,就可以使用了。打包很簡單:

在target目錄下就出現(xiàn)了jar包:

使用agent

創(chuàng)建測試類:

package com.hiwe.demo.cache;
public class TestCache {
    public static void main(String[] args) {
        System.out.println("測試類");
    }
}

添加javaagent參數(shù)配置:

-javaagent:D:\person-project\demo-agent\target\demo-agent-1.0-SNAPSHOT.jar

運行測試類:

進階(一款接口mock數(shù)據(jù)小插件)

流程

使用java agent為接口mock數(shù)據(jù)

agent類:

package com.hiwei.test.agent;
import com.hiwei.test.agent.utils.StringUtils;
import java.io.*;
import java.lang.instrument.Instrumentation;
import java.nio.charset.StandardCharsets;
public class DemoAgent {
    /**
     * 該方法在main方法之前運行
     * @param arg 文件路徑
     * @param instrumentation
     */
    public static void premain(String arg, Instrumentation instrumentation) {
        //讀取mock文件
        try {
            FileInputStream file = new FileInputStream(arg);
            BufferedReader rd = new BufferedReader(new InputStreamReader(file, StandardCharsets.UTF_8));
            String configStr = readToString(rd);
            if(StringUtils.isNotEmpty(configStr)){
                MockConfig.parseConfig(configStr);
                instrumentation.addTransformer(new DemoTransformer());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static String readToString(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int i;
        while ((i = rd.read()) != -1) {
            sb.append((char) i);
        }
        return sb.toString();
    }
}

mock數(shù)據(jù)配置類

package com.hiwei.test.agent;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MockConfig {
    private static Map<String, Map<String, Object>> mockData = new HashMap<>();
    public static void parseConfig(String configStr) {
        JSONObject config = JSONObject.parseObject(configStr);
        Set<String> classNameSet = config.keySet();
        classNameSet.forEach(className -> {
            Map<String, Object> methodMock = new HashMap<>();
            JSONObject methods = config.getJSONObject(className);
            Set<String> mSet = methods.keySet();
            mSet.forEach(m -> {
                methodMock.put(m, methods.get(m));
            });
            mockData.put(className, methodMock);
        });
    }
    public static boolean isMock(String className) {
        return !(mockData.get(className) == null);
    }
    public static Object getMockData(String className, String methodName) {
        Map<String, Object> stringJSONObjectMap = mockData.get(className);
        if (stringJSONObjectMap != null) {
            return stringJSONObjectMap.get(methodName);
        }
        return null;
    }
}

字節(jié)碼操作類

package com.hiwei.test.agent;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.lang.instrument.ClassFileTransformer;
import java.security.ProtectionDomain;
public class DemoTransformer implements ClassFileTransformer {
    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
        ClassPool classPool = ClassPool.getDefault();
        String realClassName = className.replaceAll("/", ".");
        //獲取類
        if(MockConfig.isMock(realClassName)){
            try {
                CtClass ctClass = classPool.get(realClassName);
                CtMethod[] declaredMethods = ctClass.getDeclaredMethods();
                for (CtMethod m : declaredMethods) {
                    String mName = m.getName();
                    Object mockData = MockConfig.getMockData(realClassName, mName);
                    if(mockData!=null){
                        String mock = String.format("if(true){%s}", mockData);
                        m.insertBefore(mock);
                    }
                }
                return ctClass.toBytecode();
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
        return classfileBuffer;
    }
}

配置文件:mock.json

{
  "com.hiwei.test.DemoService":{  -- 類名
    "add":"return 123;",   -- 方法名:mock代碼
    "delete":"return \"mock delete\";",
    "getUser": "com.hiwei.test.User user2 = new com.hiwei.test.User();return user2;"
  }
}

使用

配置參數(shù):

-javaagent:D:\person-project\java-agent\demo-agent\target\demo-agent-1.0-SNAPSHOT.jar=D:\person-project\java-agent\agent-test\mock.json

源碼鏈接:https://github.com/hiwei-zhang/java-agent

到此這篇關(guān)于Java Agent探針技術(shù)詳解示例的文章就介紹到這了,更多相關(guān)Java Agent內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?this調(diào)用當(dāng)前類方法無法攔截的示例代碼

    Spring?this調(diào)用當(dāng)前類方法無法攔截的示例代碼

    這篇文章主要介紹了Spring?this調(diào)用當(dāng)前類方法無法攔截,通過debug 查看這個proxyService1 和this的區(qū)別,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • SpringBoot借助spring.factories文件跨模塊實例化Bean

    SpringBoot借助spring.factories文件跨模塊實例化Bean

    這篇文章主要介紹了SpringBoot借助spring.factories文件跨模塊實例化Bean,文章圍繞主題展開詳細的內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-04-04
  • Java適配器模式定義與用法示例

    Java適配器模式定義與用法示例

    這篇文章主要介紹了Java適配器模式定義與用法,結(jié)合具體實例形式分析了java適配器模式的功能、組成、定義、使用方法及適配程度等,需要的朋友可以參考下
    2017-06-06
  • mybatis-spring:@MapperScan注解的使用

    mybatis-spring:@MapperScan注解的使用

    這篇文章主要介紹了mybatis-spring:@MapperScan注解的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • kill命令在Java應(yīng)用中使用的注意事項小結(jié)

    kill命令在Java應(yīng)用中使用的注意事項小結(jié)

    這篇文章主要給大家介紹了關(guān)于kill命令在Java應(yīng)用中使用的注意事項,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Spring Boot使用過濾器Filter過程解析

    Spring Boot使用過濾器Filter過程解析

    這篇文章主要介紹了Spring Boot使用過濾器Filter過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • 詳解springboot WebTestClient的使用

    詳解springboot WebTestClient的使用

    WebClient是一個響應(yīng)式客戶端,它提供了RestTemplate的替代方法。這篇文章主要介紹了詳解springboot WebTestClient的使用, 具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 深入理解Java原生的序列化機制

    深入理解Java原生的序列化機制

    Java 提供了一種對象序列化的機制,該機制中,一個對象可以被表示為一個字節(jié)序列,該字節(jié)序列包括該對象的數(shù)據(jù)、有關(guān)對象的類型的信息和存儲在對象中數(shù)據(jù)的類型。下面小編和大家來一起學(xué)習(xí)一下吧
    2019-06-06
  • Java 完美判斷中文字符的方法

    Java 完美判斷中文字符的方法

    Java判斷一個字符串是否有中文一般情況是利用Unicode編碼正則來做判斷,但是其實這個區(qū)間來判斷中文不是非常精確,以下是比較完善的判斷方法
    2013-02-02
  • Java?Mybatis使用resultMap時,屬性賦值順序錯誤的巨坑

    Java?Mybatis使用resultMap時,屬性賦值順序錯誤的巨坑

    這篇文章主要介紹了Java?Mybatis使用resultMap時,屬性賦值順序錯誤的巨坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論