diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Aop.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Aop.java index 49fbd735..1b00c3b1 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Aop.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/Aop.java @@ -21,6 +21,8 @@ */ package fun.asgc.neutrino.core.aop; +import fun.asgc.neutrino.core.aop.interceptor.Interceptor; +import fun.asgc.neutrino.core.aop.interceptor.InterceptorFactory; import fun.asgc.neutrino.core.aop.proxy.Proxy; import fun.asgc.neutrino.core.aop.proxy.ProxyFactory; import fun.asgc.neutrino.core.cache.Cache; @@ -130,4 +132,16 @@ public class Aop { Assert.notNull(proxyStrategy, "代理策略不能为空!"); Aop.proxyStrategy = proxyStrategy; } + + /** + * 注册全局拦截器 + * @param clazz + */ + public static void intercept(Class interceptorType) { + InterceptorFactory.registerGlobalInterceptor(interceptorType); + } + + public static void intercept(Class targetType, Class interceptorType) { + InterceptorFactory.registerInterceptor(targetType, interceptorType); + } } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/ExceptionHandlerWrapper.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/ExceptionHandlerWrapper.java new file mode 100644 index 00000000..95b1a23f --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/ExceptionHandlerWrapper.java @@ -0,0 +1,84 @@ +/** + * 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.interceptor; + +import fun.asgc.neutrino.core.util.Assert; +import fun.asgc.neutrino.core.util.LockUtil; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/7 + */ +public class ExceptionHandlerWrapper implements ExceptionHandler { + /** + * 过滤器实例 + */ + private volatile ExceptionHandler instance; + /** + * 过滤器类型 + */ + private Class type; + + private ExceptionHandlerWrapper() { + + } + + private ExceptionHandler getInstance() { + // 若未实例化,则在此先实例化 + return LockUtil.doubleCheckProcessForNoException( + () -> null == instance, + this, + () -> instance = InterceptorFactory.getOrNewExceptionHandler(type), + () -> instance + ); + } + + @Override + public boolean support(Exception e) { + return getInstance().support(e); + } + + @Override + public Object handle(Exception e) { + return getInstance().handle(e); + } + + public static ExceptionHandlerWrapper create(Class type) { + Assert.notNull(type, "异常处理器类型不能为空!"); + ExceptionHandlerWrapper wrapper = new ExceptionHandlerWrapper(); + wrapper.type = type; + return wrapper; + } + + public static ExceptionHandlerWrapper create(ExceptionHandler instance) { + Assert.notNull(instance, "异常处理器实例不能为空!"); + ExceptionHandlerWrapper wrapper = new ExceptionHandlerWrapper(); + wrapper.instance = instance; + wrapper.type = instance.getClass(); + return wrapper; + } + + public Class getType() { + return type; + } +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/FilterWrapper.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/FilterWrapper.java new file mode 100644 index 00000000..09432f4f --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/FilterWrapper.java @@ -0,0 +1,81 @@ +/** + * 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.interceptor; + +import fun.asgc.neutrino.core.util.Assert; +import fun.asgc.neutrino.core.util.LockUtil; + +import java.lang.reflect.Method; + +/** + * filter包装器 + * @author: aoshiguchen + * @date: 2022/7/7 + */ +public class FilterWrapper implements Filter { + /** + * 过滤器实例 + */ + private volatile Filter instance; + /** + * 过滤器类型 + */ + private Class type; + + private FilterWrapper() { + + } + + private Filter getInstance() { + // 若未实例化,则在此先实例化 + return LockUtil.doubleCheckProcessForNoException( + () -> null == instance, + this, + () -> instance = InterceptorFactory.getOrNewFilter(type), + () -> instance + ); + } + + @Override + public boolean filtration(Class targetClass, Method targetMethod, Object[] args) { + return getInstance().filtration(targetClass, targetMethod, args); + } + + public static FilterWrapper create(Class type) { + Assert.notNull(type, "过滤器类型不能为空!"); + FilterWrapper wrapper = new FilterWrapper(); + wrapper.type = type; + return wrapper; + } + + public static FilterWrapper create(Filter instance) { + Assert.notNull(instance, "过滤器实例不能为空!"); + FilterWrapper wrapper = new FilterWrapper(); + wrapper.instance = instance; + wrapper.type = instance.getClass(); + return wrapper; + } + + public Class getType() { + return type; + } +} 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 2525a16a..7f2630d4 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 @@ -84,10 +84,88 @@ public class InterceptorFactory { * @param * @return */ - public static T get(Class clazz) { + public static T getOrNew(Class clazz) { return (T)getOrNewCacheBean(clazz, interceptorCache); } + /** + * 获取过滤器实例 + * @param clazz + * @param + * @return + */ + public static T getOrNewFilter(Class clazz) { + return (T)getOrNewCacheBean(clazz, filterCache); + } + + /** + * 获取过滤器列表 + * @param classes + * @param + * @return + */ + public static List getOrNewFilterList(Class[] classes) { + if (ArrayUtil.isEmpty(classes)) { + return null; + } + return Stream.of(classes).map(c -> (T)getOrNewFilter(c)).filter(Objects::nonNull).collect(Collectors.toList()); + } + + /** + * 获取结果处理器实例 + * @param clazz + * @param + * @return + */ + public static T getOrNewResultAdvice(Class clazz) { + return (T)getOrNewCacheBean(clazz, resultAdviceCache); + } + + /** + * 获取结果处理器列表 + * @param classes + * @param + * @return + */ + public static List getOrNewResultAdviceList(Class[] classes) { + if (ArrayUtil.isEmpty(classes)) { + return null; + } + return Stream.of(classes).map(c -> (T)getOrNewResultAdvice(c)).filter(Objects::nonNull).collect(Collectors.toList()); + } + + /** + * 获取异常处理器实例 + * @param clazz + * @param + * @return + */ + public static T getOrNewExceptionHandler(Class clazz) { + return (T)getOrNewCacheBean(clazz, exceptionHandlerCache); + } + + /** + * 获取异常处理器列表 + * @param classes + * @param + * @return + */ + public static List getOrNewExceptionHandlerList(Class[] classes) { + if (ArrayUtil.isEmpty(classes)) { + return null; + } + return Stream.of(classes).map(c -> (T)getOrNewExceptionHandler(c)).filter(Objects::nonNull).collect(Collectors.toList()); + } + + /** + * 获取拦截器实例 + * @param clazz + * @return + */ + public static Interceptor get(Class clazz) { + return InterceptorWrapper.create(clazz); + } + /** * 获取过滤器实例 * @param clazz @@ -170,6 +248,9 @@ public class InterceptorFactory { () -> { List interceptors = new ArrayList<>(); interceptors.addAll(globalInterceptorList); + if (classInterceptorListMap.containsKey(targetMethod.getDeclaringClass())) { + interceptors.addAll(classInterceptorListMap.get(targetMethod.getDeclaringClass())); + } addInterceptorByAnnotation(interceptors, targetMethod.getDeclaringClass().getAnnotation(Intercept.class)); addInterceptorByAnnotation(interceptors, targetMethod.getAnnotation(Intercept.class)); // 如果被代理方法所属类是一个接口,那么该接口所有继承接口链路上的注解都对该方法生效 @@ -196,24 +277,24 @@ public class InterceptorFactory { return; } if (ArrayUtil.notEmpty(intercept.filter()) || ArrayUtil.notEmpty(intercept.resultAdvice()) || ArrayUtil.notEmpty(intercept.exceptionHandler())) { - DefaultInterceptor wrapper = new DefaultInterceptor(); + DefaultInterceptor interceptor = new DefaultInterceptor(); List filterList = getFilterList(intercept.filter()); List resultAdviceList = getResultAdviceList(intercept.resultAdvice()); List exceptionHandlerList = getExceptionHandlerList(intercept.exceptionHandler()); if (CollectionUtil.notEmpty(filterList)) { - wrapper.registerFilter(filterList); + interceptor.registerFilter(filterList); } if (CollectionUtil.notEmpty(resultAdviceList)) { - wrapper.registerResultAdvice(resultAdviceList); + interceptor.registerResultAdvice(resultAdviceList); } if (CollectionUtil.notEmpty(exceptionHandlerList)) { - wrapper.registerExceptionHandler(exceptionHandlerList); + interceptor.registerExceptionHandler(exceptionHandlerList); } - interceptors.add(wrapper); + interceptors.add(interceptor); } if (ArrayUtil.notEmpty(intercept.value())) { for (Class clazz : intercept.value()) { - Interceptor interceptor = get(clazz); + Interceptor interceptor = getOrNew(clazz); if (null != interceptor && !interceptors.contains(interceptor)) { interceptors.add(interceptor); } @@ -222,13 +303,11 @@ public class InterceptorFactory { if (ArrayUtil.notEmpty(intercept.exclude())) { for (Class clazz : intercept.exclude()) { Interceptor interceptor = get(clazz); - if (null != interceptor && interceptors.contains(interceptor)) { - interceptors.remove(interceptor); - } + removeInterceptor(interceptors, interceptor); } } if (intercept.ignoreGlobal()) { - interceptors.removeAll(globalInterceptorList); + removeInterceptor(interceptors, globalInterceptorList); } } @@ -239,8 +318,143 @@ public class InterceptorFactory { public static synchronized void registerGlobalInterceptor(Class clazz) { Assert.notNull(clazz, "class不能为空!"); Interceptor interceptor = get(clazz); - if (!globalInterceptorList.contains(interceptor)) { + if (!containsInterceptor(globalInterceptorList, interceptor)) { globalInterceptorList.add(interceptor); } } + + /** + * 注册类的拦截器 + * @param targetType + * @param interceptorType + */ + public static synchronized void registerInterceptor(Class targetType, Class interceptorType) { + Assert.notNull(targetType, "目标类型不能为空不能为空!"); + Assert.notNull(targetType, "目标类型不能为空不能为空!"); + if (!classInterceptorListMap.containsKey(targetType)) { + classInterceptorListMap.put(targetType, new ArrayList<>()); + } + Interceptor interceptor = get(interceptorType); + if (!containsInterceptor(classInterceptorListMap.get(targetType), interceptor)) { + classInterceptorListMap.get(targetType).add(interceptor); + } + } + + + /** + * 删除指定拦截器 + * @param list + * @param removeList + */ + private static void removeInterceptor(List list, List removeList) { + if (CollectionUtil.isEmpty(list) || CollectionUtil.isEmpty(removeList)) { + return; + } + removeList.forEach(item -> removeInterceptor(list, item)); + } + + private static boolean containsInterceptor(List list, Interceptor interceptor) { + if (CollectionUtil.isEmpty(list) || null == interceptor) { + return false; + } + Iterator iter = list.iterator(); + while (iter.hasNext()) { + Interceptor item = iter.next(); + if (typeEquals(item, interceptor)) { + return true; + } + } + return false; + } + + /** + * 删除指定拦截器 + * @param list + * @param interceptor + */ + private static void removeInterceptor(List list, Interceptor interceptor) { + if (CollectionUtil.isEmpty(list) || null == interceptor) { + return; + } + Iterator iter = list.iterator(); + while (iter.hasNext()) { + Interceptor item = iter.next(); + if (typeEquals(item, interceptor)) { + iter.remove(); + return; + } + } + } + + private static boolean typeEquals(Interceptor a, Interceptor b) { + if (a == b) { + return true; + } + if (null == a || null == b) { + return false; + } + Class type1 = a.getClass(); + Class type2 = b.getClass(); + if (a instanceof InterceptorWrapper) { + type1 = ((InterceptorWrapper)a).getType(); + } + if (b instanceof InterceptorWrapper) { + type2 = ((InterceptorWrapper)b).getType(); + } + return type1 == type2; + } + + private static boolean typeEquals(Filter a, Filter b) { + if (a == b) { + return true; + } + if (null == a || null == b) { + return false; + } + Class type1 = a.getClass(); + Class type2 = b.getClass(); + if (a instanceof FilterWrapper) { + type1 = ((FilterWrapper)a).getType(); + } + if (b instanceof FilterWrapper) { + type2 = ((FilterWrapper)b).getType(); + } + return type1 == type2; + } + + private static boolean typeEquals(ResultAdvice a, ResultAdvice b) { + if (a == b) { + return true; + } + if (null == a || null == b) { + return false; + } + Class type1 = a.getClass(); + Class type2 = b.getClass(); + if (a instanceof ResultAdviceWrapper) { + type1 = ((ResultAdviceWrapper)a).getType(); + } + if (b instanceof ResultAdviceWrapper) { + type2 = ((ResultAdviceWrapper)b).getType(); + } + return type1 == type2; + } + + private static boolean typeEquals(ExceptionHandler a, ExceptionHandler b) { + if (a == b) { + return true; + } + if (null == a || null == b) { + return false; + } + Class type1 = a.getClass(); + Class type2 = b.getClass(); + if (a instanceof ExceptionHandlerWrapper) { + type1 = ((ExceptionHandlerWrapper)a).getType(); + } + if (b instanceof ExceptionHandlerWrapper) { + type2 = ((ExceptionHandlerWrapper)b).getType(); + } + return type1 == type2; + } } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorWrapper.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorWrapper.java index abd5ba5d..70fc7d10 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorWrapper.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/InterceptorWrapper.java @@ -47,15 +47,20 @@ public class InterceptorWrapper implements Interceptor { } - @Override - public void intercept(Invocation inv) throws Exception { + + private Interceptor getInstance() { // 若未实例化,则在此先实例化 - LockUtil.doubleCheckProcess( + return LockUtil.doubleCheckProcessForNoException( () -> null == instance, this, - () -> InterceptorFactory.get(type) + () -> instance = InterceptorFactory.getOrNew(type), + () -> instance ); - instance.intercept(inv); + } + + @Override + public void intercept(Invocation inv) throws Exception { + getInstance().intercept(inv); } public static InterceptorWrapper create(Class type) { @@ -72,4 +77,8 @@ public class InterceptorWrapper implements Interceptor { wrapper.type = instance.getClass(); return wrapper; } + + public Class getType() { + return type; + } } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/ResultAdviceWrapper.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/ResultAdviceWrapper.java new file mode 100644 index 00000000..ce767e25 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/aop/interceptor/ResultAdviceWrapper.java @@ -0,0 +1,82 @@ +/** + * 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.interceptor; + +import fun.asgc.neutrino.core.util.Assert; +import fun.asgc.neutrino.core.util.LockUtil; + +import java.lang.reflect.Method; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/7 + */ +public class ResultAdviceWrapper implements ResultAdvice { + /** + * 过滤器实例 + */ + private volatile ResultAdvice instance; + /** + * 过滤器类型 + */ + private Class type; + + private ResultAdviceWrapper() { + + } + + private ResultAdvice getInstance() { + // 若未实例化,则在此先实例化 + return LockUtil.doubleCheckProcessForNoException( + () -> null == instance, + this, + () -> instance = InterceptorFactory.getOrNewResultAdvice(type), + () -> instance + ); + } + + @Override + public Object advice(Class targetClass, Method targetMethod, Object result) { + return getInstance().advice(targetClass, targetMethod, result); + } + + + public static ResultAdviceWrapper create(Class type) { + Assert.notNull(type, "过滤器类型不能为空!"); + ResultAdviceWrapper wrapper = new ResultAdviceWrapper(); + wrapper.type = type; + return wrapper; + } + + public static ResultAdviceWrapper create(ResultAdvice instance) { + Assert.notNull(instance, "过滤器实例不能为空!"); + ResultAdviceWrapper wrapper = new ResultAdviceWrapper(); + wrapper.instance = instance; + wrapper.type = instance.getClass(); + return wrapper; + } + + public Class getType() { + return type; + } +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test5.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test5.java new file mode 100644 index 00000000..09a18f9b --- /dev/null +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/aop/Test5.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/7/7 + */ +public class Test5 { + + @Test + public void test1() throws Exception { + Aop.intercept(Panda.class, TestInterceptor.class); + Panda panda = Aop.get(Panda.class); + panda.eat(); + } +}