From 72ce626a278b40a7018383cec4d779f7b2b78dd0 Mon Sep 17 00:00:00 2001
From: aoshiguchen <1052045476@qq.com>
Date: Wed, 6 Jul 2022 15:46:37 +0800
Subject: [PATCH] =?UTF-8?q?Aop=E5=AD=90=E7=B1=BB=E4=BB=A3=E7=90=86?=
=?UTF-8?q?=E7=94=9F=E6=88=90=E4=BB=A3=E7=90=86=E7=B1=BB=E6=BA=90=E7=A0=81?=
=?UTF-8?q?=E6=94=B9=E4=B8=BA=E4=BD=BF=E7=94=A8=E6=A8=A1=E6=9D=BF=E5=BC=95?=
=?UTF-8?q?=E6=93=8E=E7=94=9F=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
neutrino-core/pom.xml | 5 +
.../aop/interceptor/InterceptorFactory.java | 12 +-
.../core/aop/proxy/AsgcProxyFactory.java | 167 +-----------------
.../core/aop/proxy/AsgcProxyGenerator.java | 165 +++++++++++++++++
.../src/main/resources/tpl/AsgcProxy.tpl | 48 +++++
.../core/aop/AsgcProxyGeneratorTest.java | 40 +++++
.../fun/asgc/neutrino/core/aop/Test3.java | 8 +-
7 files changed, 271 insertions(+), 174 deletions(-)
create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyGenerator.java
create mode 100644 neutrino-core/src/main/resources/tpl/AsgcProxy.tpl
create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/AsgcProxyGeneratorTest.java
diff --git a/neutrino-core/pom.xml b/neutrino-core/pom.xml
index d903271c..52f916d6 100644
--- a/neutrino-core/pom.xml
+++ b/neutrino-core/pom.xml
@@ -33,6 +33,11 @@
8.0.29
test
+
+ org.apache.velocity
+ velocity-engine-core
+ 2.2
+
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorFactory.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorFactory.java
index c537a56f..abd14493 100644
--- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorFactory.java
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorFactory.java
@@ -60,11 +60,13 @@ public class InterceptorFactory {
clazz,
() -> {
try {
- if (BeanManager.getBean(clazz) != null) {
- cache.set(clazz, BeanManager.getBean(clazz));
- } else {
- cache.set(clazz, clazz.newInstance());
- }
+ // TODO
+ cache.set(clazz, clazz.newInstance());
+// if (BeanManager.getBean(clazz) != null) {
+// cache.set(clazz, BeanManager.getBean(clazz));
+// } else {
+// cache.set(clazz, clazz.newInstance());
+// }
} catch (InstantiationException|IllegalAccessException e) {
throw new RuntimeException(e);
}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyFactory.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyFactory.java
index 74b14dbf..d2651ba2 100644
--- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyFactory.java
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyFactory.java
@@ -21,18 +21,10 @@
*/
package fun.asgc.neutrino.core.aop.proxy;
-import fun.asgc.neutrino.core.aop.Invocation;
import fun.asgc.neutrino.core.util.*;
import lombok.extern.slf4j.Slf4j;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Parameter;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -74,7 +66,7 @@ public class AsgcProxyFactory implements ProxyFactory {
private T doGet(Class clazz) throws ReflectiveOperationException {
ProxyClass proxyClass = new ProxyClass(clazz);
proxyClass.setName(generateClassName(clazz));
- String sourceCode = generateProxyClassSourceCode(clazz, proxyClass.getName());
+ String sourceCode = AsgcProxyGenerator.getInstance().generator(proxyClass.getName(), clazz); // generateProxyClassSourceCode(clazz, proxyClass.getName());
proxyClass.setSourceCode(sourceCode);
log.debug("类:{} 的代理类源码:\n{}", clazz.getName(), sourceCode);
@@ -87,161 +79,4 @@ public class AsgcProxyFactory implements ProxyFactory {
private String generateClassName(Class> clazz) {
return String.format(classNameTemplate, clazz.getSimpleName(), proxyClassCounter.incrementAndGet());
}
-
- /**
- * 生成代理类源代码 - 继承方式
- * 1、类不能有final修饰符
- * 2、被代理方法不能有final修饰符
- * @param clazz
- * @return
- */
- private String generateProxyClassSourceCode(Class> clazz, String proxyClassName) {
- if (ClassUtil.isInterface(clazz)) {
- return generateProxyClassSourceCodeForInterface(clazz, proxyClassName);
- }
- Set> importClasses = new HashSet<>();
- StringBuilder header = new StringBuilder();
- header.append("package " + clazz.getPackage().getName() + ";").append("\n");
- appendImport(header, Invocation.class, importClasses);
- appendImport(header, ProxyCache.class, importClasses);
-
- StringBuilder body = new StringBuilder();
- body.append("public class ").append(proxyClassName).append(" extends ").append(clazz.getSimpleName()).append("{\n");
- Method[] methods = clazz.getMethods();
- if (ArrayUtil.notEmpty(methods)) {
- for (Method method : methods) {
- if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
- continue;
- }
- Long methodId = ProxyCache.setMethod(method);
- Class> returnType = method.getReturnType();
- Set> exceptionTypes = ReflectUtil.getExceptionTypes(method);
- boolean isVoid = returnType == void.class;
- boolean isThrow = CollectionUtil.notEmpty(exceptionTypes);
- String parametersString = buildParametersString(method.getParameters());
- String parameterNamesString = buildParameterNamesString(method.getParameters());
- String throwString = isThrow ? "throws " + buildTypeNameString(exceptionTypes) : "";
- if (isThrow) {
- for (Class> c : exceptionTypes) {
- appendImport(header, c, importClasses);
- }
- }
-
- body.append("\t").append("public").append(" ").append(returnType.getName()).append(" ").append(method.getName()).append("(").append(parametersString).append(") ").append(throwString).append(" {").append("\n")
- .append("\t\tInvocation inv = new Invocation(").append(methodId + "L,").append("this,").append("() -> {").append("\n")
- .append("\t\t\t").append(isVoid ? "" : "return ").append("super.").append(method.getName()).append("(").append(parameterNamesString).append(");").append("\n")
- .append(isVoid ? "\t\t\treturn null;\n" : "")
- .append("\t\t").append("}").append(StringUtil.isEmpty(parameterNamesString) ? "" : "," + parameterNamesString).append(");").append("\n")
- .append("\t\t").append("try {\n")
- .append("\t\t\t").append("inv.invoke();").append("\n")
- .append("\t\t").append("} catch (Exception e) {\n");
-
- if (isThrow) {
- body.append("\t\t\t").append("if (ProxyCache.checkMethodThrow(" + methodId + "L,e)) {").append("\n")
- .append("\t\t\t\t").append("throw e;").append("\n")
- .append("\t\t\t").append("} else {").append("\n")
- .append("\t\t\t\t").append("e.printStackTrace();").append("\n")
- .append("\t\t\t").append("}").append("\n");
- } else {
- body.append("\t\t\t").append("e.printStackTrace();").append("\n");
- }
- body.append("\t\t").append("}\n")
- .append(isVoid ? "" : "\t\treturn inv.getReturnValue();\n")
- .append("\t").append("}").append("\n");
- }
- }
- body.append("}").append("\n");
- return header.toString().concat(body.toString());
- }
-
- private String generateProxyClassSourceCodeForInterface(Class> clazz, String proxyClassName) {
- Set> importClasses = new HashSet<>();
- StringBuilder header = new StringBuilder();
- header.append("package " + clazz.getPackage().getName() + ";").append("\n");
- appendImport(header, Invocation.class, importClasses);
- appendImport(header, ProxyCache.class, importClasses);
-
- StringBuilder body = new StringBuilder();
- body.append("public class ").append(proxyClassName).append(" implements ").append(clazz.getSimpleName()).append("{\n");
- Method[] methods = clazz.getMethods();
- if (ArrayUtil.notEmpty(methods)) {
- for (Method method : methods) {
- if (Modifier.isFinal(method.getModifiers())) {
- continue;
- }
- Long methodId = ProxyCache.setMethod(method);
- Class> returnType = method.getReturnType();
- Set> exceptionTypes = ReflectUtil.getExceptionTypes(method);
- boolean isVoid = returnType == void.class;
- boolean isThrow = CollectionUtil.notEmpty(exceptionTypes);
- String parametersString = buildParametersString(method.getParameters());
- String parameterNamesString = buildParameterNamesString(method.getParameters());
- String throwString = isThrow ? "throws " + buildTypeNameString(exceptionTypes) : "";
- if (isThrow) {
- for (Class> c : exceptionTypes) {
- appendImport(header, c, importClasses);
- }
- }
-
- body.append("\t").append("public").append(" ").append(returnType.getName()).append(" ").append(method.getName()).append("(").append(parametersString).append(") ").append(throwString).append(" {").append("\n")
- .append("\t\tInvocation inv = new Invocation(").append(methodId + "L,").append("this,").append("() -> {").append("\n")
- .append("\t\t\treturn null;\n")
- .append("\t\t").append("}").append(StringUtil.isEmpty(parameterNamesString) ? "" : "," + parameterNamesString).append(");").append("\n")
- .append("\t\t").append("try {\n")
- .append("\t\t\t").append("inv.invoke();").append("\n")
- .append("\t\t").append("} catch (Exception e) {\n");
-
- if (isThrow) {
- body.append("\t\t\t").append("if (ProxyCache.checkMethodThrow(" + methodId + "L,e)) {").append("\n")
- .append("\t\t\t\t").append("throw e;").append("\n")
- .append("\t\t\t").append("} else {").append("\n")
- .append("\t\t\t\t").append("e.printStackTrace();").append("\n")
- .append("\t\t\t").append("}").append("\n");
- } else {
- body.append("\t\t\t").append("e.printStackTrace();").append("\n");
- }
- body.append("\t\t").append("}\n")
- .append(isVoid ? "" : "\t\treturn inv.getReturnValue();\n")
- .append("\t").append("}").append("\n");
-
- }
- }
- body.append("}").append("\n");
- return header.toString().concat(body.toString());
- }
-
- /**
- * 追加import语句,java.lang包下不需要import
- * @param sb
- * @param clazz
- * @param importClasses
- */
- private synchronized void appendImport(StringBuilder sb, Class> clazz, Set> importClasses) {
- if (importClasses.contains(clazz) || clazz.getName().startsWith("java.lang.")) {
- return;
- }
- importClasses.add(clazz);
- sb.append("import ").append(clazz.getName()).append(";\n");
- }
-
- private String buildParametersString(Parameter[] parameters) {
- if (ArrayUtil.isEmpty(parameters)) {
- return "";
- }
- return Stream.of(parameters).map(item -> item.getType().getName() + " " + item.getName()).collect(Collectors.joining(","));
- }
-
- private String buildParameterNamesString(Parameter[] parameters) {
- if (ArrayUtil.isEmpty(parameters)) {
- return "";
- }
- return Stream.of(parameters).map(Parameter::getName).collect(Collectors.joining(","));
- }
-
- private String buildTypeNameString(Set> classes) {
- if (CollectionUtil.isEmpty(classes)) {
- return "";
- }
- return classes.stream().map(Class::getName).collect(Collectors.joining(","));
- }
}
diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyGenerator.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyGenerator.java
new file mode 100644
index 00000000..d2cc4c37
--- /dev/null
+++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/AsgcProxyGenerator.java
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.aop.proxy;
+
+import fun.asgc.neutrino.core.aop.Invocation;
+import fun.asgc.neutrino.core.util.*;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import sun.management.MethodInfo;
+
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ *
+ * @author: aoshiguchen
+ * @date: 2022/7/6
+ */
+@SuppressWarnings("all")
+public class AsgcProxyGenerator {
+ private static final AsgcProxyGenerator instance = new AsgcProxyGenerator();
+ private VelocityEngine engine;
+ private Template template;
+
+ private AsgcProxyGenerator() {
+ engine = new VelocityEngine();
+ engine.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+ engine.init();
+ template = engine.getTemplate("tpl/AsgcProxy.tpl");
+ }
+
+ private String render(Map map) {
+ VelocityContext context = new VelocityContext(map);
+ StringWriter stringWriter = new StringWriter();
+ template.merge(context, stringWriter);
+ return stringWriter.toString();
+ }
+
+ public String generator(String proxyClassName, Class> targetType) {
+ Map map = new HashMap<>();
+ map.put("package", targetType.getPackage().getName());
+ List> importList = new ArrayList<>();
+ map.put("importList", importList);
+ appendImport(importList, Invocation.class);
+ appendImport(importList, ProxyCache.class);
+ map.put("proxyClassName", proxyClassName);
+ map.put("targetType", targetType);
+ map.put("targetIsInterface", ClassUtil.isInterface(targetType));
+
+ List methodInfoList = new ArrayList<>();
+ map.put("methodInfoList", methodInfoList);
+
+ Method[] methods = targetType.getMethods();
+ if (ArrayUtil.notEmpty(methods)) {
+ for (Method method : methods) {
+ if (Modifier.isFinal(method.getModifiers()) || Modifier.isStatic(method.getModifiers())) {
+ continue;
+ }
+ Long methodId = ProxyCache.setMethod(method);
+ Class> returnType = method.getReturnType();
+ boolean isVoid = returnType == void.class;
+ appendImport(importList, returnType);
+ if (ArrayUtil.notEmpty(method.getParameters())) {
+ Stream.of(method.getParameters()).forEach(parameter -> appendImport(importList, parameter.getType()));
+ }
+ Set> exceptionTypes = ReflectUtil.getExceptionTypes(method);
+ boolean isThrow = CollectionUtil.notEmpty(exceptionTypes);
+ String throwsString = isThrow ? " throws " + buildTypeNameString(exceptionTypes) + " ": " ";
+ if (CollectionUtil.notEmpty(exceptionTypes)) {
+ exceptionTypes.forEach(exceptionType -> appendImport(importList, exceptionType));
+ }
+
+ String parameterNamesString = buildParameterNamesString(method.getParameters());
+ methodInfoList.add(new MethodInfo()
+ .setMethodId(methodId)
+ .setReturnType(returnType)
+ .setVoid(isVoid)
+ .setMethodName(method.getName())
+ .setParametersString(buildParametersString(method.getParameters()))
+ .setThrowsString(throwsString)
+ .setThrow(isThrow)
+ .setParameterNamesString(parameterNamesString)
+ );
+ }
+ }
+ return render(map);
+ }
+
+ public static AsgcProxyGenerator getInstance() {
+ return instance;
+ }
+
+ private String buildParametersString(Parameter[] parameters) {
+ if (ArrayUtil.isEmpty(parameters)) {
+ return "";
+ }
+ return Stream.of(parameters).map(item -> item.getType().getSimpleName() + " " + item.getName()).collect(Collectors.joining(", "));
+ }
+
+ private String buildTypeNameString(Set> classes) {
+ if (CollectionUtil.isEmpty(classes)) {
+ return "";
+ }
+ return classes.stream().map(Class::getSimpleName).collect(Collectors.joining(","));
+ }
+
+ private String buildParameterNamesString(Parameter[] parameters) {
+ if (ArrayUtil.isEmpty(parameters)) {
+ return "";
+ }
+ return Stream.of(parameters).map(Parameter::getName).collect(Collectors.joining(", "));
+ }
+
+ /**
+ * 追加import语句,java.lang包下不需要import
+ * @param importClasses
+ * @param clazz
+ */
+ private synchronized void appendImport(List> importClasses, Class> clazz) {
+ if (importClasses.contains(clazz) || clazz.getName().startsWith("java.lang.") || TypeUtil.isNormalBasicType(clazz) || clazz == void.class) {
+ return;
+ }
+ importClasses.add(clazz);
+ }
+
+ @Accessors(chain = true)
+ @Data
+ public static class MethodInfo {
+ private Long methodId;
+ private Class> returnType;
+ private boolean isVoid;
+ private String methodName;
+ private String parametersString;
+ private String throwsString;
+ private boolean isThrow;
+ private String parameterNamesString;
+ }
+}
diff --git a/neutrino-core/src/main/resources/tpl/AsgcProxy.tpl b/neutrino-core/src/main/resources/tpl/AsgcProxy.tpl
new file mode 100644
index 00000000..a6811b5c
--- /dev/null
+++ b/neutrino-core/src/main/resources/tpl/AsgcProxy.tpl
@@ -0,0 +1,48 @@
+package ${package};
+
+#foreach($item in ${importList})
+import ${item.getName()};
+#end
+
+#if(${targetIsInterface})
+public class ${proxyClassName} implements ${targetType.getSimpleName()} {
+#else
+public class ${proxyClassName} extends ${targetType.getSimpleName()} {
+#end
+
+#foreach($methodInfo in ${methodInfoList})
+ public ${methodInfo.returnType.getSimpleName()} ${methodInfo.methodName} (${methodInfo.parametersString})${methodInfo.throwsString}{
+ Invocation inv = new Invocation(${methodInfo.methodId}L, this, () -> {
+#if(!${targetIsInterface})
+#if(${methodInfo.void})
+ super.${methodInfo.methodName}(${methodInfo.parameterNamesString});
+ return null;
+#else
+ return super.${methodInfo.methodName}(${methodInfo.parameterNamesString});
+#end
+#else
+ return null;
+#end
+ });
+ try {
+ inv.invoke();
+ } catch(RuntimeException e) {
+ throw e;
+ } catch(Exception e) {
+#if(${methodInfo.throw})
+ if (ProxyCache.checkMethodThrow(${methodInfo.methodId}L, e)) {
+ throw e;
+ } else {
+ e.printStackTrace();
+ }
+#else
+ e.printStackTrace();
+#end
+ }
+#if(!${methodInfo.void})
+ return inv.getReturnValue();
+#end
+ }
+
+#end
+}
diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/AsgcProxyGeneratorTest.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/AsgcProxyGeneratorTest.java
new file mode 100644
index 00000000..cebf5f0c
--- /dev/null
+++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/AsgcProxyGeneratorTest.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2022 aoshiguchen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+package fun.asgc.neutrino.core.aop;
+
+import fun.asgc.neutrino.core.aop.proxy.AsgcProxyGenerator;
+import org.junit.Test;
+
+/**
+ *
+ * @author: aoshiguchen
+ * @date: 2022/7/6
+ */
+public class AsgcProxyGeneratorTest {
+
+ @Test
+ public void test1() {
+ String result = AsgcProxyGenerator.getInstance().generator("A", Panda.class);
+ System.out.println(result);
+ }
+
+}
diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test3.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test3.java
index 9f88b2d5..a036c698 100644
--- a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test3.java
+++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test3.java
@@ -21,6 +21,7 @@
*/
package fun.asgc.neutrino.core.aop;
+import fun.asgc.neutrino.core.aop.proxy.Proxy;
import fun.asgc.neutrino.core.util.ReflectUtil;
import org.junit.Test;
@@ -36,15 +37,16 @@ public class Test3 {
@Test
public void test1() throws Exception {
- Animal animal = Aop.get(Animal.class);
-// Animal animal = Proxy.getProxyFactory(ProxyStrategy.ASGC_PROXY).get(Animal.class);
+// Animal animal = Aop.get(Animal.class);
+ Animal animal = Proxy.getProxyFactory(ProxyStrategy.ASGC_PROXY).get(Animal.class);
System.out.println(animal);
System.out.println(animal.say("aa"));
}
@Test
public void test2() throws Exception {
- Mammal mammal = Aop.get(Mammal.class);
+// Mammal mammal = Aop.get(Mammal.class);
+ Mammal mammal = Proxy.getProxyFactory(ProxyStrategy.ASGC_PROXY).get(Mammal.class);
mammal.crawl();
System.out.println(ReflectUtil.getInterfaceAll(Mammal.class));