diff --git a/agent.properties b/agent.properties index 486af52..6a51543 100644 --- a/agent.properties +++ b/agent.properties @@ -1,6 +1,8 @@ # mock文件路径 -foxMockFilePath=/Users/yinjihuan/Downloads/foxmockdata +foxMockFilePath=/Users/yinjihuan/Documents/foxmockdata # foxmock的agent jar包路径,不填默认为当前文件夹 -foxMockAgentJarPath=fox-mock-agent/target/fox-mock-agent-2.0-SNAPSHOT.jar +foxMockAgentJarPath=fox-mock-agent/target/fox-mock-agent-3.0.jar # mock方法白名单,如果文件夹中有多个方法会被全部mock,如果指定了此配置将只会mock这里指定的方法 -mockMethodWhiteList=com.cxytiandi.foxmock.example.UserService#getAge|com.cxytiandi.foxmock.example.UserService#getAddrs \ No newline at end of file +#mockMethodWhiteList=com.cxytiandi.foxmock.example.UserService#getAge|com.cxytiandi.foxmock.example.UserService#getName2 +# httpn mock数据地址,可以对接配置中心,必须是get请求 +#mockDataHttpUrl=http%3A%2F%2F47.105.66.210%3A8848%2Fnacos%2Fv1%2Fcs%2Fconfigs%3FdataId%3Dfox-mock%26group%3DDEFAULT_GROUP%26tenant%3D9c9f5197-688c-4ef9-ae68-1ff28663301d \ No newline at end of file diff --git a/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/FoxMockAgent.java b/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/FoxMockAgent.java index c0dfb74..d5a59b6 100644 --- a/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/FoxMockAgent.java +++ b/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/FoxMockAgent.java @@ -26,6 +26,10 @@ */ public class FoxMockAgent { + static { + System.setProperty("arthas.logback.configurationFile", "foxmock-logback.xml"); + } + private static final Logger LOG = LoggerFactory.getLogger(FoxMockAgent.class); private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1, new ThreadFactory() { diff --git a/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/transformer/MockClassFileTransformer.java b/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/transformer/MockClassFileTransformer.java index 1f0aa17..a2a91e9 100644 --- a/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/transformer/MockClassFileTransformer.java +++ b/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/transformer/MockClassFileTransformer.java @@ -60,8 +60,10 @@ public byte[] transform(ClassLoader loader, String className, Class classBein if (Objects.nonNull(data)) { match = true; LOG.info(String.format("mock methods %s, mock data is %s", key, data)); - String mockCode = "if(true){com.cxytiandi.foxmock.agent.gson.Gson gson = new com.cxytiandi.foxmock.agent.gson.Gson();return ($r)gson.fromJson(%s, $type);}"; - method.insertBefore(String.format(mockCode, new Gson().toJson(data))); + String mockCode = "if(true){" + + "return ($r)com.cxytiandi.foxmock.agent.utils.JsonUtils.parse(%s,%s,%s);" + + "}"; + method.insertBefore(String.format(mockCode, new Gson().toJson(data), "\""+className+"\"", "\""+methodName+"\"")); } } diff --git a/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/utils/JsonUtils.java b/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/utils/JsonUtils.java new file mode 100644 index 0000000..98d9df6 --- /dev/null +++ b/fox-mock-agent/src/main/java/com/cxytiandi/foxmock/agent/utils/JsonUtils.java @@ -0,0 +1,38 @@ +package com.cxytiandi.foxmock.agent.utils; + +import com.google.gson.Gson; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +/** + * JSON转换工具类,由于javassist不支持泛型,所以采用了一个折中的方式,在这里处理好带泛型的对象 + * + * @作者 尹吉欢 + * @个人微信 jihuan900 + * @微信公众号 猿天地 + * @GitHub https://github.com/yinjihuan + * @作者介绍 http://cxytiandi.com/about + * @时间 2022-05-06 21:20 + */ +public class JsonUtils { + + public static Object parse(String data, String className, String methodName) { + try { + Type genericReturnType = null; + Class clazz = Class.forName(className.replace('/','.')); + Method[] declaredMethods = clazz.getDeclaredMethods(); + for (Method m: declaredMethods) { + if (m.getName().equals(methodName)){ + genericReturnType = m.getGenericReturnType(); + break; + } + } + + Gson gson = new Gson(); + Object value = gson.fromJson(data, genericReturnType); + return value; + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/fox-mock-boot/src/main/java/com/cxytiandi/foxmock/boot/Bootstrap.java b/fox-mock-boot/src/main/java/com/cxytiandi/foxmock/boot/Bootstrap.java index ee98ec9..0d5a942 100644 --- a/fox-mock-boot/src/main/java/com/cxytiandi/foxmock/boot/Bootstrap.java +++ b/fox-mock-boot/src/main/java/com/cxytiandi/foxmock/boot/Bootstrap.java @@ -31,7 +31,7 @@ public static void main(String[] args) { String mockDataHttpUrl = config.getProperty("mockDataHttpUrl", ""); if (Objects.isNull(foxMockAgentJarPath)) { - foxMockAgentJarPath = PathUtils.getAgentPath() + File.separator + "fox-mock-agent-2.0.jar"; + foxMockAgentJarPath = PathUtils.getAgentPath() + File.separator + "fox-mock-agent-3.0.jar"; } VirtualMachine attach = VirtualMachine.attach(String.valueOf(getPid())); diff --git a/fox-mock-example/pom.xml b/fox-mock-example/pom.xml index 12a988d..2ca0d9d 100644 --- a/fox-mock-example/pom.xml +++ b/fox-mock-example/pom.xml @@ -11,10 +11,33 @@ fox-mock-example + + + + org.springframework.boot + spring-boot-dependencies + 2.3.1.RELEASE + pom + import + + + + com.google.code.gson gson + + + org.springframework.boot + spring-boot-starter-web + + \ No newline at end of file diff --git a/fox-mock-example/src/main/java/com/cxytiandi/foxmock/example/FoxMockApp.java b/fox-mock-example/src/main/java/com/cxytiandi/foxmock/example/FoxMockApp.java index a8d9871..8784578 100644 --- a/fox-mock-example/src/main/java/com/cxytiandi/foxmock/example/FoxMockApp.java +++ b/fox-mock-example/src/main/java/com/cxytiandi/foxmock/example/FoxMockApp.java @@ -1,5 +1,9 @@ package com.cxytiandi.foxmock.example; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import java.util.Map; +import java.util.Objects; /** * @作者 尹吉欢 @@ -9,22 +13,33 @@ * @作者介绍 http://cxytiandi.com/about * @时间 2022-04-18 22:11 */ +@SpringBootApplication public class FoxMockApp { - public static void main(String[] args) throws Exception { - while (true) { - UserService userService = new UserService(); - System.out.println(String.format("你好 %s", userService.getName2().getId())); - System.out.println(String.format("你好 %s", userService.getAge())); - System.out.println(String.format("你好 %s", userService.getAddrs())); - System.out.println(String.format("你好 %s", userService.getUsers())); - System.out.println(String.format("你好 %s", userService.getUsers2())); - System.out.println(String.format("你好 %s", userService.getUser())); - System.out.println(String.format("你好 %s", userService.getUserDetail())); - System.out.println("----------------------------------------"); - Thread.sleep(5000); - } + SpringApplication.run(FoxMockApp.class); + + while (true) { + UserService userService = new UserService(); + System.out.println(String.format("你好 %s", userService.getName2().getId())); + System.out.println(String.format("你好 %s", userService.getAge())); + System.out.println(String.format("你好 %s", userService.getAddrs())); + System.out.println(String.format("你好 %s", userService.getUsers())); + System.out.println(String.format("你好 %s", userService.getUsers2())); + System.out.println(String.format("你好 %s", userService.getUser())); + System.out.println(String.format("你好 %s", userService.getUserDetail())); + // 泛型测试 + Result userDetailResult = userService.getUserDetail(); + UserDetail userDetail = userDetailResult.getData(); + if (Objects.nonNull(userDetail)) { + Map addressMap = userDetail.getAddressMap(); + addressMap.forEach((k,v) -> { + System.out.println(k + "\t" + v.getAddress()); + }); + } + System.out.println("----------------------------------------"); + Thread.sleep(5000); + } } }