aop优化,支持代理接口,接口代理支持拦截器继承

This commit is contained in:
aoshiguchen
2022-06-28 18:50:43 +08:00
parent e5e3a3c0d7
commit 78e1fb8bc2
4 changed files with 83 additions and 3 deletions
@@ -24,9 +24,7 @@ package fun.asgc.neutrino.core.aop.interceptor;
import fun.asgc.neutrino.core.aop.Intercept;
import fun.asgc.neutrino.core.cache.Cache;
import fun.asgc.neutrino.core.cache.MemoryCache;
import fun.asgc.neutrino.core.util.ArrayUtil;
import fun.asgc.neutrino.core.util.Assert;
import fun.asgc.neutrino.core.util.LockUtil;
import fun.asgc.neutrino.core.util.*;
import java.lang.reflect.Method;
import java.util.*;
@@ -67,6 +65,15 @@ public class InterceptorFactory {
() -> {
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(globalInterceptorList);
// 如果被代理方法所属类是一个接口,那么该接口所有继承接口链路上的注解都对该方法生效
if (ClassUtil.isInterface(targetMethod.getDeclaringClass())) {
List<Class<?>> interfaceList = ReflectUtil.getInterfaceAll(targetMethod.getDeclaringClass());
if (CollectionUtil.notEmpty(interfaceList)) {
for (Class<?> clazz : interfaceList) {
addInterceptorByAnnotation(interceptors, clazz.getAnnotation(Intercept.class));
}
}
}
addInterceptorByAnnotation(interceptors, targetMethod.getDeclaringClass().getAnnotation(Intercept.class));
addInterceptorByAnnotation(interceptors, targetMethod.getAnnotation(Intercept.class));
methodInterceptorListMap.put(targetMethod, interceptors);
@@ -23,6 +23,7 @@
package fun.asgc.neutrino.core.util;
import com.google.common.collect.Sets;
import fun.asgc.neutrino.core.base.Orderly;
import fun.asgc.neutrino.core.cache.Cache;
import fun.asgc.neutrino.core.cache.MemoryCache;
import fun.asgc.neutrino.core.type.TypeMatchLevel;
@@ -377,4 +378,33 @@ public class ReflectUtil {
}
return false;
}
/**
* 获取该类的所有接口,并保持按照接口层级的顺序(顶级在最前、其次是第二级、...)
* @param clazz
* @return
*/
public static List<Class<?>> getInterfaceAll(Class<?> clazz) {
List<Orderly<Class<?>>> list = new ArrayList<>();
if (ArrayUtil.notEmpty(clazz.getInterfaces())) {
addTo(list, clazz.getInterfaces(), 0);
int current = 0;
while (current < list.size()) {
Orderly<Class<?>> peek = list.get(current);
if (ArrayUtil.notEmpty(peek.getData().getInterfaces())) {
addTo(list, peek.getData().getInterfaces(), peek.getOrder() + 1);
}
current++;
}
}
return list.stream().sorted().map(Orderly::getData).collect(Collectors.toList());
}
private static void addTo(List<Orderly<Class<?>>> list, Class<?>[] classes, int level) {
if (ArrayUtil.notEmpty(classes)) {
for (Class<?> clazz : classes) {
list.add(new Orderly<Class<?>>().setData(clazz).setOrder(Integer.MAX_VALUE - level));
}
}
}
}
@@ -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
*/
public interface Mammal extends Animal {
/**
* 爬行
*/
void crawl();
}
@@ -21,6 +21,7 @@
*/
package fun.asgc.neutrino.core.aop;
import fun.asgc.neutrino.core.util.ReflectUtil;
import org.junit.Test;
/**
@@ -36,4 +37,12 @@ public class Test3 {
System.out.println(animal);
System.out.println(animal.say("aa"));
}
@Test
public void test2() {
Mammal mammal = Aop.get(Mammal.class);
mammal.crawl();
System.out.println(ReflectUtil.getInterfaceAll(Mammal.class));
}
}