SpringBoot实现多数据源的切换实践
324
2022-07-23
目录什么是java agent?使用示例入门进阶(一款接口mock数据小插件)使用
什么是java agent?
在JVM中运行中,类是通过classLoader加载.class文件进行生成的。在类加载加载.class文件生成对应的类对象之前时,我们可以通过修改.class文件内容(就是字节码修改技术),达到修改类的目的。JDK提供了对字节码进行操作的一系列api,而使用这些api开发出的程序就可以称之为java agent。
java agent能做什么?
不修改目标应用达到代码增强的目的,就好像spring的aop一样,但是java agent是直接修改字节码,而不是通过创建代理类。例如skywalking就是使用java agent技术,为目标应用代码植入监控代码,监控代码进行数据统计上报的。这种方式实现了解耦,通用的功能。
文末附上了我写的一款接口mock agent。感兴趣的可以看看,学习一波。
使用示例
入门
创建maven工程
创建一个简单的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("执行premain方法");
}
}
pom.xml打包配置
添加打包插件:
将工程打成jar包,就可以使用了。打包很简单:
在target目录下就出现了jar包:
使用agent
创建测试类:
package com.hiwe.demo.cache;
public class TestCache {
public static void main(String[] args) {
System.out.println("测试类");
}
}
添加javaagent参数配置:
-javaagent:D:\person-project\demo-agent\target\demo-agent-1.0-SNAPSHOT.jar
运行测试类:
进阶(一款接口mock数据小插件)
流程
使用java agent为接口mock数据
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) ihttp://);
}
return sb.toString();
}
}
mock数据配置类
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
public static void parseConfig(String configStr) {
JSONObject config = JSONObject.parseObject(configStr);
Set
classNameSet.forEach(className -> {
Map
JSONObject methods = config.getJSONObject(className);
Set
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
if (stringJSONObjectMap != null) {
return stringJSONObjectMap.get(methodName);
}
return null;
}
}
字节码操作类
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&swVJRDGXquot;:"return \"mock delete\";", "getUser": "com.hiwei.test.User user2 = new com.hiwei.test.User();return user2;" }}
使用
配置参数:
-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
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~