From e5e3a3c0d7d4b2f883d9a6c18681b1c0005eb313 Mon Sep 17 00:00:00 2001 From: aoshiguchen <1052045476@qq.com> Date: Tue, 28 Jun 2022 18:13:05 +0800 Subject: [PATCH] =?UTF-8?q?aop=E4=BC=98=E5=8C=96=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BB=A3=E7=90=86=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../asgc/neutrino/core/aop/Invocation.java | 4 ++ .../interceptor/InnerGlobalInterceptor.java | 4 ++ .../core/aop/proxy/SubClassProxyFactory.java | 38 +++++++++++++++++- .../asgc/neutrino/core/db/annotation/Id.java | 7 ++++ .../core/db/annotation/PrimaryKey.java | 7 ++++ .../neutrino/core/db/annotation/Select.java | 30 ++++++++++++++ .../neutrino/core/db/mapper/SqlMapper.java | 30 ++++++++++++++ .../fun/asgc/neutrino/core/aop/Animal.java | 34 ++++++++++++++++ .../java/fun/asgc/neutrino/core/aop/Cat.java | 2 +- .../fun/asgc/neutrino/core/aop/Test3.java | 39 +++++++++++++++++++ 10 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Select.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/db/mapper/SqlMapper.java create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Animal.java create mode 100644 neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test3.java diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Invocation.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Invocation.java index d2ba9aa5..2c182cee 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Invocation.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Invocation.java @@ -68,6 +68,10 @@ public class Invocation { return (T)returnValue; } + public Class getReturnType() { + return targetMethod.getReturnType(); + } + public void setReturnValue(Object returnValue) { this.returnValue = returnValue; } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InnerGlobalInterceptor.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InnerGlobalInterceptor.java index 26b6d3a6..e9212a38 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InnerGlobalInterceptor.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InnerGlobalInterceptor.java @@ -23,6 +23,7 @@ package fun.asgc.neutrino.core.aop.interceptor; import fun.asgc.neutrino.core.aop.Invocation; import fun.asgc.neutrino.core.util.CollectionUtil; +import fun.asgc.neutrino.core.util.TypeUtil; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; @@ -59,6 +60,9 @@ public class InnerGlobalInterceptor implements Interceptor { result = advice.advice(inv.getTargetClass(), inv.getTargetMethod(), result); } } + if (null == result) { + result = TypeUtil.getDefaultValue(inv.getReturnType()); + } inv.setReturnValue(result); log.debug("内置顶层拦截器 class:{} method:{} args:{} result:{} finished.", inv.getTargetClass().getName(), inv.getTargetMethod().getName(), inv.getArgs(), result); diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/SubClassProxyFactory.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/SubClassProxyFactory.java index 0d57fc37..a33fda7a 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/SubClassProxyFactory.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/proxy/SubClassProxyFactory.java @@ -60,12 +60,13 @@ public class SubClassProxyFactory implements ProxyFactory { @Override public boolean canProxy(Class clazz) { - return !ClassUtil.isFinal(clazz) + return ClassUtil.isInterface(clazz) || + (!ClassUtil.isFinal(clazz) && !ClassUtil.isAbstract(clazz) && ClassUtil.isPublic(clazz) && !ClassUtil.isStatic(clazz) && !ClassUtil.isInterface(clazz) - && Stream.of(clazz.getConstructors()).filter(e -> e.getParameterCount() == 0).count() > 0; + && Stream.of(clazz.getConstructors()).filter(e -> e.getParameterCount() == 0).count() > 0); } private T doGet(Class clazz) throws ReflectiveOperationException { @@ -93,6 +94,9 @@ public class SubClassProxyFactory implements ProxyFactory { * @return */ private String generateProxyClassSourceCode(Class clazz, String proxyClassName) { + if (ClassUtil.isInterface(clazz)) { + return generateProxyClassSourceCodeForInterface(clazz, proxyClassName); + } StringBuilder sb = new StringBuilder(); sb.append("package " + clazz.getPackage().getName() + ";").append("\n"); sb.append("import ").append(Invocation.class.getName()).append(";\n"); @@ -123,6 +127,36 @@ public class SubClassProxyFactory implements ProxyFactory { return sb.toString(); } + private String generateProxyClassSourceCodeForInterface(Class clazz, String proxyClassName) { + StringBuilder sb = new StringBuilder(); + sb.append("package " + clazz.getPackage().getName() + ";").append("\n"); + sb.append("import ").append(Invocation.class.getName()).append(";\n"); + sb.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(); + boolean isVoid = returnType == void.class; + String parametersString = buildParametersString(method.getParameters()); + String parameterNamesString = buildParameterNamesString(method.getParameters()); + + sb.append("\t").append("public").append(" ").append(returnType.getName()).append(" ").append(method.getName()).append("(").append(parametersString).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("inv.invoke();").append("\n") + .append(isVoid ? "" : "\t\treturn inv.getReturnValue();\n") + .append("\t").append("}").append("\n"); + } + } + sb.append("}").append("\n"); + return sb.toString(); + } + private String buildParametersString(Parameter[] parameters) { if (ArrayUtil.isEmpty(parameters)) { return ""; diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java index dcb04770..093e4e64 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Id.java @@ -21,12 +21,19 @@ */ package fun.asgc.neutrino.core.db.annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + /** * Id * 在持久化模型中标注单一主键 * @author: aoshiguchen * @date: 2022/6/27 */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) public @interface Id { } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java index 55e0de10..ffcebffb 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/PrimaryKey.java @@ -21,12 +21,19 @@ */ package fun.asgc.neutrino.core.db.annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + /** * PrimaryKey * 在持久化模型中标注主键(可标注一个或多个) * @author: aoshiguchen * @date: 2022/6/27 */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) public @interface PrimaryKey { } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Select.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Select.java new file mode 100644 index 00000000..f294e8d4 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/annotation/Select.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd. + *

+ * All right reserved. + *

+ * This software is the confidential and proprietary + * information of Zeyi Company of China. + * ("Confidential Information"). You shall not disclose + * such Confidential Information and shall use it only + * in accordance with the terms of the contract agreement + * you entered into with Zeyi inc. + */ +package fun.asgc.neutrino.core.db.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author: wen.y + * @date: 2022/6/28 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Select { + String sql(); + Class resultType(); +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/mapper/SqlMapper.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/mapper/SqlMapper.java new file mode 100644 index 00000000..69322c7b --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/db/mapper/SqlMapper.java @@ -0,0 +1,30 @@ +/** + * 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.db.mapper; + +/** + * @author: aoshiguchen + * @date: 2022/6/28 + */ +public interface SqlMapper { + +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Animal.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Animal.java new file mode 100644 index 00000000..bf8916bb --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Animal.java @@ -0,0 +1,34 @@ +/** + * 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; + +/** + * + * @author: aoshiguchen + * @date: 2022/6/28 + */ +@Intercept(TestInterceptor.class) +public interface Animal { + + int say(String msg); + +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Cat.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Cat.java index 6035a40e..5bd913de 100644 --- a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Cat.java +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Cat.java @@ -26,7 +26,7 @@ package fun.asgc.neutrino.core.aop; * @author: aoshiguchen * @date: 2022/6/24 */ -public class Cat { +public class Cat { public Cat() { System.out.println("猫出生"); } 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 new file mode 100644 index 00000000..7209341f --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test3.java @@ -0,0 +1,39 @@ +/** + * 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 org.junit.Test; + +/** + * + * @author: aoshiguchen + * @date: 2022/6/28 + */ +public class Test3 { + + @Test + public void test1() { + Animal animal = Aop.get(Animal.class); + System.out.println(animal); + System.out.println(animal.say("aa")); + } +}