All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nepxion.matrix.proxy.aop.AbstractAutoScanProxy Maven / Gradle / Ivy

Go to download

Nepxion Matrix is an AOP framework integrated with Spring AutoProxy, Spring Registrar and Spring Import Selector

There is a newer version: 3.0.0
Show newest version
package com.nepxion.matrix.proxy.aop;

/**
 * 

Title: Nepxion Matrix

*

Description: Nepxion Matrix AOP

*

Copyright: Copyright (c) 2017-2050

*

Company: Nepxion

* @author Haojun Ren * @version 1.0 */ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.aopalliance.intercept.MethodInterceptor; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.AopProxyUtils; import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; import org.springframework.beans.BeansException; import org.springframework.stereotype.Component; import com.nepxion.matrix.proxy.constant.ProxyConstant; import com.nepxion.matrix.proxy.mode.ProxyMode; import com.nepxion.matrix.proxy.mode.ScanMode; import com.nepxion.matrix.proxy.util.ProxyUtil; public abstract class AbstractAutoScanProxy extends AbstractAutoProxyCreator { private static final long serialVersionUID = 6827218905375993727L; private static final Logger LOG = LoggerFactory.getLogger(AbstractAutoScanProxy.class); static { String logoShown = System.getProperty("nepxion.logo.shown", "true"); if (Boolean.valueOf(logoShown)) { System.out.println(""); System.out.println("╔═╗╔═╗ ╔╗"); System.out.println("║║╚╝║║ ╔╝╚╗"); System.out.println("║╔╗╔╗╠══╬╗╔╬═╦╦╗╔╗"); System.out.println("║║║║║║╔╗║║║║╔╬╬╬╬╝"); System.out.println("║║║║║║╔╗║║╚╣║║╠╬╬╗"); System.out.println("╚╝╚╝╚╩╝╚╝╚═╩╝╚╩╝╚╝"); System.out.println("Nepxion Matrix - AutoScanProxy v2.0.4"); System.out.println(""); } } // Bean名称和Bean对象关联 private final Map beanMap = new HashMap(); // Spring容器中哪些接口或者类需要被代理 private final Map proxyMap = new HashMap(); // Spring容器中哪些类是类代理,哪些类是通过它的接口做代理 private final Map proxyTargetClassMap = new HashMap(); // 扫描目录,如果不指定,则扫描全局。两种方式运行结果没区别,只是指定扫描目录加快扫描速度,同时可以减少缓存量 private String[] scanPackages; // 通过注解确定代理 private ProxyMode proxyMode; // 扫描注解后的处理 private ScanMode scanMode; public AbstractAutoScanProxy() { this((String[]) null); } public AbstractAutoScanProxy(String scanPackages) { this(scanPackages, ProxyMode.BY_CLASS_OR_METHOD_ANNOTATION, ScanMode.FOR_CLASS_OR_METHOD_ANNOTATION); } public AbstractAutoScanProxy(String[] scanPackages) { this(scanPackages, ProxyMode.BY_CLASS_OR_METHOD_ANNOTATION, ScanMode.FOR_CLASS_OR_METHOD_ANNOTATION); } public AbstractAutoScanProxy(ProxyMode proxyMode, ScanMode scanMode) { this((String[]) null, proxyMode, scanMode); } public AbstractAutoScanProxy(String scanPackages, ProxyMode proxyMode, ScanMode scanMode) { this(scanPackages, proxyMode, scanMode, true); } public AbstractAutoScanProxy(String[] scanPackages, ProxyMode proxyMode, ScanMode scanMode) { this(scanPackages, proxyMode, scanMode, true); } public AbstractAutoScanProxy(ProxyMode proxyMode, ScanMode scanMode, boolean exposeProxy) { this((String[]) null, proxyMode, scanMode, exposeProxy); } public AbstractAutoScanProxy(String scanPackages, ProxyMode proxyMode, ScanMode scanMode, boolean exposeProxy) { this(StringUtils.isNotEmpty(scanPackages) ? scanPackages.trim().split(ProxyConstant.SEPARATOR) : null, proxyMode, scanMode, exposeProxy); } public AbstractAutoScanProxy(String[] scanPackages, ProxyMode proxyMode, ScanMode scanMode, boolean exposeProxy) { this.scanPackages = scanPackages; this.setExposeProxy(exposeProxy); this.proxyMode = proxyMode; this.scanMode = scanMode; StringBuilder builder = new StringBuilder(); if (ArrayUtils.isNotEmpty(scanPackages)) { for (int i = 0; i < scanPackages.length; i++) { String scanPackage = scanPackages[i]; builder.append(scanPackage); if (i < scanPackages.length - 1) { builder.append(ProxyConstant.SEPARATOR); } } } LOG.info("------------- Matrix Aop Information ------------"); LOG.info("Auto scan proxy class is {}", getClass().getCanonicalName()); LOG.info("Scan packages is {}", ArrayUtils.isNotEmpty(scanPackages) ? builder.toString() : "not set"); LOG.info("Proxy mode is {}", proxyMode); LOG.info("Scan mode is {}", scanMode); LOG.info("Expose proxy is {}", exposeProxy); LOG.info("-------------------------------------------------"); // 设定全局拦截器,可以是多个 // 如果同时设置了全局和额外的拦截器,那么它们都同时工作,全局拦截器先运行,额外拦截器后运行 Class[] commonInterceptorClasses = getCommonInterceptors(); String[] commonInterceptorNames = getCommonInterceptorNames(); String[] interceptorNames = ArrayUtils.addAll(commonInterceptorNames, convertInterceptorNames(commonInterceptorClasses)); if (ArrayUtils.isNotEmpty(interceptorNames)) { setInterceptorNames(interceptorNames); } } private String[] convertInterceptorNames(Class[] commonInterceptorClasses) { if (ArrayUtils.isNotEmpty(commonInterceptorClasses)) { String[] interceptorNames = new String[commonInterceptorClasses.length]; for (int i = 0; i < commonInterceptorClasses.length; i++) { Class interceptorClass = commonInterceptorClasses[i]; interceptorNames[i] = interceptorClass.getAnnotation(Component.class).value(); } return interceptorNames; } return null; } @Override protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, TargetSource targetSource) { boolean scanPackagesEnabled = scanPackagesEnabled(); // scanPackagesEnabled=false,表示“只扫描指定目录”的方式未开启,则不会对扫描到的bean进行代理预先判断 if (scanPackagesEnabled) { boolean scanPackagesContained = scanPackagesContained(beanClass); // 如果beanClass的类路径,未包含在扫描目录中,返回DO_NOT_PROXY if (!scanPackagesContained) { return DO_NOT_PROXY; } } // 根据Bean名称获取Bean对象 Object bean = beanMap.get(beanName); // 获取最终目标类 Class targetClass = null; if (bean != null /* && AopUtils.isCglibProxy(bean) */) { targetClass = AopProxyUtils.ultimateTargetClass(bean); } else { targetClass = beanClass; } // Spring容器扫描实现类 if (!targetClass.isInterface()) { // 扫描接口(从实现类找到它的所有接口) if (targetClass.getInterfaces() != null) { for (Class targetInterface : targetClass.getInterfaces()) { Object[] proxyInterceptors = scanAndProxyForTarget(targetInterface, beanName, false); if (proxyInterceptors != DO_NOT_PROXY) { return proxyInterceptors; } } } // 扫描实现类(如果接口上没找到注解, 就找实现类的注解) Object[] proxyInterceptors = scanAndProxyForTarget(targetClass, beanName, true); if (proxyInterceptors != DO_NOT_PROXY) { return proxyInterceptors; } } return DO_NOT_PROXY; } protected Object[] scanAndProxyForTarget(Class targetClass, String beanName, boolean proxyTargetClass) { String targetClassName = targetClass.getCanonicalName(); Object[] interceptors = getInterceptors(targetClass); // 排除java开头的接口,例如java.io.Serializable,java.io.Closeable等,执行不被代理 if (StringUtils.isNotEmpty(targetClassName) && !targetClassName.startsWith("java.")) { // 避免对同一个接口或者类扫描多次 Boolean proxied = proxyMap.get(targetClassName); if (proxied != null) { if (proxied) { return interceptors; } } else { Object[] proxyInterceptors = null; switch (proxyMode) { // 只通过扫描到接口名或者类名上的注解后,来确定是否要代理 case BY_CLASS_ANNOTATION_ONLY: proxyInterceptors = scanAndProxyForClass(targetClass, targetClassName, beanName, interceptors, proxyTargetClass); break; // 只通过扫描到接口或者类方法上的注解后,来确定是否要代理 case BY_METHOD_ANNOTATION_ONLY: proxyInterceptors = scanAndProxyForMethod(targetClass, targetClassName, beanName, interceptors, proxyTargetClass); break; // 上述两者都可以 case BY_CLASS_OR_METHOD_ANNOTATION: Object[] classProxyInterceptors = scanAndProxyForClass(targetClass, targetClassName, beanName, interceptors, proxyTargetClass); // 没有接口或者类名上扫描到目标注解,那么扫描接口或者类的方法上的目标注解 Object[] methodProxyInterceptors = scanAndProxyForMethod(targetClass, targetClassName, beanName, interceptors, proxyTargetClass); if (classProxyInterceptors != DO_NOT_PROXY || methodProxyInterceptors != DO_NOT_PROXY) { proxyInterceptors = interceptors; } else { proxyInterceptors = DO_NOT_PROXY; } break; } // 是否需要代理 proxyMap.put(targetClassName, Boolean.valueOf(proxyInterceptors != DO_NOT_PROXY)); if (proxyInterceptors != DO_NOT_PROXY) { // 是接口代理还是类代理 proxyTargetClassMap.put(beanName, proxyTargetClass); LOG.info("------------ Matrix Proxy Information -----------"); Class[] commonInterceptorClasses = getCommonInterceptors(); if (ArrayUtils.isNotEmpty(commonInterceptorClasses)) { LOG.info("Class [{}] is proxied by common interceptor classes [{}], proxyTargetClass={}", targetClassName, ProxyUtil.toString(commonInterceptorClasses), proxyTargetClass); } String[] commonInterceptorNames = getCommonInterceptorNames(); if (ArrayUtils.isNotEmpty(commonInterceptorNames)) { LOG.info("Class [{}] is proxied by common interceptor beans [{}], proxyTargetClass={}", targetClassName, ProxyUtil.toString(commonInterceptorNames), proxyTargetClass); } if (proxyInterceptors != PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS && ArrayUtils.isNotEmpty(proxyInterceptors)) { LOG.info("Class [{}] is proxied by additional interceptors [{}], proxyTargetClass={}", targetClassName, proxyInterceptors, proxyTargetClass); } LOG.info("-------------------------------------------------"); } return proxyInterceptors; } } return DO_NOT_PROXY; } protected Object[] scanAndProxyForClass(Class targetClass, String targetClassName, String beanName, Object[] interceptors, boolean proxyTargetClass) { // 判断目标注解是否标注在接口名或者类名上 boolean proxied = false; Class[] classAnnotations = getClassAnnotations(); if (ArrayUtils.isNotEmpty(classAnnotations)) { for (Class classAnnotation : classAnnotations) { if (targetClass.isAnnotationPresent(classAnnotation)) { // 是否执行“注解扫描后处理” if (scanMode == ScanMode.FOR_CLASS_ANNOTATION_ONLY || scanMode == ScanMode.FOR_CLASS_OR_METHOD_ANNOTATION) { classAnnotationScanned(targetClass, classAnnotation); } else { // 如果“注解扫描后处理”不开启,没必要再往下执行循环,直接返回 return interceptors; } // 目标注解被扫描到,proxied赋值为true,即认为该接口或者类被代理 if (!proxied) { proxied = true; } } } } return proxied ? interceptors : DO_NOT_PROXY; } protected Object[] scanAndProxyForMethod(Class targetClass, String targetClassName, String beanName, Object[] interceptors, boolean proxyTargetClass) { // 判断目标注解是否标注在方法上 boolean proxied = false; Class[] methodAnnotations = getMethodAnnotations(); if (ArrayUtils.isNotEmpty(methodAnnotations)) { for (Method method : targetClass.getDeclaredMethods()) { for (Class methodAnnotation : methodAnnotations) { if (method.isAnnotationPresent(methodAnnotation)) { // 是否执行“注解扫描后处理” if (scanMode == ScanMode.FOR_METHOD_ANNOTATION_ONLY || scanMode == ScanMode.FOR_CLASS_OR_METHOD_ANNOTATION) { methodAnnotationScanned(targetClass, method, methodAnnotation); } else { // 如果“注解扫描后处理”不开启,没必要再往下执行循环,直接返回 return interceptors; } // 目标注解被扫描到,proxied赋值为true,即认为该接口或者类被代理 if (!proxied) { proxied = true; } } } } } return proxied ? interceptors : DO_NOT_PROXY; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { Object object = super.postProcessBeforeInitialization(bean, beanName); // 前置扫描,把Bean名称和Bean对象关联存入Map boolean scanPackagesEnabled = scanPackagesEnabled(); if (scanPackagesEnabled) { boolean scanPackagesContained = scanPackagesContained(bean.getClass()); if (scanPackagesContained) { // 如果beanClass的类路径,包含在扫描目录中,则加入beanMap beanMap.put(beanName, bean); } } else { // scanPackagesEnabled=false,表示“只扫描指定目录”的方式未开启,则所有扫描到的bean都加入beanMap beanMap.put(beanName, bean); } return object; } @Override protected boolean shouldProxyTargetClass(Class beanClass, String beanName) { // 设置不同场景下的接口代理,还是类代理 Boolean proxyTargetClass = proxyTargetClassMap.get(beanName); if (proxyTargetClass != null) { return proxyTargetClass; } return super.shouldProxyTargetClass(beanClass, beanName); } // 是否是“只扫描指定目录”的方式 protected boolean scanPackagesEnabled() { return ArrayUtils.isNotEmpty(scanPackages); } // 是否指定的beanClass包含在扫描目录中 protected boolean scanPackagesContained(Class beanClass) { for (String scanPackage : scanPackages) { if (StringUtils.isNotEmpty(scanPackage)) { // beanClassName有时候会为null... String beanClassName = beanClass.getCanonicalName(); if (StringUtils.isNotEmpty(beanClassName)) { if (beanClassName.startsWith(scanPackage) || beanClassName.contains(ProxyConstant.JDK_PROXY_NAME_KEY) || beanClassName.contains(ProxyConstant.CGLIB_PROXY_NAME_KEY)) { return true; } } else { return false; } } } return false; } // 获取切面拦截类的方式 // 1. 根据targetClass从额外拦截类列表中去取(接口代理targetClass是接口类,类代理targetClass是类) // 2. 如果从额外拦截类列表中没取到,就从全局拦截类列表中去取(PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS) // 3. 如果从全局拦截类列表中没取到,就不代理(DO_NOT_PROXY) protected Object[] getInterceptors(Class targetClass) { Object[] interceptors = getAdditionalInterceptors(targetClass); if (ArrayUtils.isNotEmpty(interceptors)) { return interceptors; } Class[] commonInterceptorClasses = getCommonInterceptors(); String[] commonInterceptorNames = getCommonInterceptorNames(); if (ArrayUtils.isNotEmpty(commonInterceptorClasses) || ArrayUtils.isNotEmpty(commonInterceptorNames)) { return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS; } return DO_NOT_PROXY; } // 返回具有调用拦截的全局切面实现类,拦截类必须实现MethodInterceptor接口, 可以多个,通过@Component("xxx")方式寻址 // 如果返回null, 全局切面代理关闭 protected abstract Class[] getCommonInterceptors(); // 返回具有调用拦截的全局切面实现类的Bean名,拦截类必须实现MethodInterceptor接口, 可以多个 // 如果返回null, 全局切面代理关闭 protected abstract String[] getCommonInterceptorNames(); // 返回额外的拦截类实例列表,拦截类必须实现MethodInterceptor接口,分别对不同的接口或者类赋予不同的拦截类,可以多个 // 如果返回null, 额外切面代理关闭 protected abstract MethodInterceptor[] getAdditionalInterceptors(Class targetClass); // 返回接口名或者类名上的注解列表,可以多个, 如果接口名或者类名上存在一个或者多个该列表中的注解,即认为该接口或者类需要被代理和扫描 // 如果返回null,则对列表中的注解不做代理和扫描 protected abstract Class[] getClassAnnotations(); // 返回接口或者类的方法名上的注解,可以多个,如果接口或者类中方法名上存在一个或者多个该列表中的注解,即认为该接口或者类需要被代理和扫描 // 如果返回null,则对列表中的注解不做代理和扫描 protected abstract Class[] getMethodAnnotations(); // 一旦指定的接口或者类名上的注解被扫描到,将会触发该方法 protected abstract void classAnnotationScanned(Class targetClass, Class classAnnotation); // 一旦指定的接口或者类的方法名上的注解被扫描到,将会触发该方法 protected abstract void methodAnnotationScanned(Class targetClass, Method method, Class methodAnnotation); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy