Spring AOP基础组件 AdviceSpring AOP基础组件 Advisor 简介
定义了切面的匹配点,即哪些类的哪些方法;在Spring AOP中匹配点主要是class(ClassFilter)和method(MethodFilter)两个维度;
源码 Pointcutpublic interface Pointcut { // 类过滤器,用于匹配类 ClassFilter getClassFilter(); // 方法匹配器,用于匹配方法 MethodMatcher getMethodMatcher(); // 默认匹配所有类的所有方法 Pointcut TRUE = TruePointcut.INSTANCE;}
TruePointcutfinal class TruePointcut implements Pointcut, Serializable { public static final TruePointcut INSTANCE = new TruePointcut(); private TruePointcut() { } // 匹配任何类 @Override public ClassFilter getClassFilter() { return ClassFilter.TRUE; } // 匹配任何方法 @Override public MethodMatcher getMethodMatcher() { return MethodMatcher.TRUE; }}
ClassFilter@FunctionalInterfacepublic interface ClassFilter { // 是否匹配指定的接口/类 boolean matches(Class<?> clazz); // 匹配任意类型的示例 ClassFilter TRUE = TrueClassFilter.INSTANCE;}
TrueClassFilterfinal class TrueClassFilter implements ClassFilter, Serializable { public static final TrueClassFilter INSTANCE = new TrueClassFilter(); // 确保单例 private TrueClassFilter() { } @Override public boolean matches(Class<?> clazz) { // 全匹配 return true; }}
MethodMatcherpublic interface MethodMatcher { // 是否静态地匹配指定类的指定方法 boolean matches(Method method, Class<?> targetClass); // 是否动态匹配 boolean isRuntime(); // 是否动态地匹配指定类的指定方法 boolean matches(Method method, Class<?> targetClass, Object..、args); // 匹配任意方法的示例 MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;}
TrueMethodMatcherfinal class TrueMethodMatcher implements MethodMatcher, Serializable { public static final TrueMethodMatcher INSTANCE = new TrueMethodMatcher(); // 确保单例 private TrueMethodMatcher() { } @Override public boolean isRuntime() { // 静态匹配 return false; } @Override public boolean matches(Method method, Class<?> targetClass) { // 匹配任意类的任意方法 return true; } @Override public boolean matches(Method method, Class<?> targetClass, Object..、args) { // 抛出不支持操作异常 throw new UnsupportedOperationException(); }}
实现子类 ControlFlowPointcut 简介根据在当前现成的堆栈信息中的方法名来决定是否切入某个方法;
核心代码public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher, Serializable { // 匹配的类名,必须有效 private final Class<?> clazz; // 匹配的方法名,支持为null,表示匹配任意方法 @Nullable private final String methodName; // 计数器 private final AtomicInteger evaluations = new AtomicInteger(); public ControlFlowPointcut(Class<?> clazz, @Nullable String methodName) { // 校验类名的有效性 Assert.notNull(clazz, "Class must not be null"); this.clazz = clazz; this.methodName = methodName; } @Override public boolean matches(Class<?> clazz) { // 匹配任意类 return true; } @Override public boolean matches(Method method, Class<?> targetClass) { // 匹配任意类的任意方法 return true; } @Override public boolean isRuntime() { // 动态匹配 return true; } @Override public boolean matches(Method method, Class<?> targetClass, Object..、args) { // 记录次数 this.evaluations.incrementAndGet(); // 遍历方法调用栈 for (StackTraceElement element : new Throwable().getStackTrace()) { // 当前方法是否匹配类名和方法名 if (element.getClassName().equals(this.clazz.getName()) && (this.methodName == null || element.getMethodName().equals(this.methodName))) { return true; } } return false; } @Override public ClassFilter getClassFilter() { return this; } @Override public MethodMatcher getMethodMatcher() { return this; }}
ComposablePointcut 简介组合模式的Pointcut;
核心代码public class ComposablePointcut implements Pointcut, Serializable { private ClassFilter classFilter; private MethodMatcher methodMatcher; public ComposablePointcut() { this.classFilter = ClassFilter.TRUE; this.methodMatcher = MethodMatcher.TRUE; } public ComposablePointcut union(ClassFilter other) { // 类过滤器并集 this.classFilter = ClassFilters.union(this.classFilter, other); return this; } public ComposablePointcut intersection(ClassFilter other) { // 类过滤器交集 this.classFilter = ClassFilters.intersection(this.classFilter, other); return this; } public ComposablePointcut union(MethodMatcher other) { // 方法匹配器并集 this.methodMatcher = MethodMatchers.union(this.methodMatcher, other); return this; } public ComposablePointcut intersection(MethodMatcher other) { // 方法匹配器交集 this.methodMatcher = MethodMatchers.intersection(this.methodMatcher, other); return this; } public ComposablePointcut union(Pointcut other) { // 方法匹配器并集 this.methodMatcher = MethodMatchers.union( this.methodMatcher, this.classFilter, other.getMethodMatcher(), other.getClassFilter()); // 类过滤器并集 this.classFilter = ClassFilters.union(this.classFilter, other.getClassFilter()); return this; } public ComposablePointcut intersection(Pointcut other) { // 类过滤器交集 this.classFilter = ClassFilters.intersection(this.classFilter, other.getClassFilter()); // 方法匹配器交集 this.methodMatcher = MethodMatchers.intersection(this.methodMatcher, other.getMethodMatcher()); return this; } @Override public ClassFilter getClassFilter() { return this.classFilter; } @Override public MethodMatcher getMethodMatcher() { return this.methodMatcher; }}
DynamicMethodMatcherPointcut 简介动态匹配的Pointcut;
核心代码public abstract class DynamicMethodMatcherPointcut extends DynamicMethodMatcher implements Pointcut { @Override public ClassFilter getClassFilter() { // 匹配任意类 return ClassFilter.TRUE; } @Override public final MethodMatcher getMethodMatcher() { return this; }}
DynamicMethodMatcherpublic abstract class DynamicMethodMatcher implements MethodMatcher { @Override public final boolean isRuntime() { // 动态匹配 return true; } @Override public boolean matches(Method method, Class<?> targetClass) { // 静态匹配默认匹配 return true; }}
StaticMethodMatcherPointcut 简介静态匹配的Pointcut;
核心代码public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut { // 类过滤器,默认匹配任意类 private ClassFilter classFilter = ClassFilter.TRUE; public void setClassFilter(ClassFilter classFilter) { // 设置类过滤器 this.classFilter = classFilter; } @Override public ClassFilter getClassFilter() { return this.classFilter; } @Override public final MethodMatcher getMethodMatcher() { return this; }}
StaticMethodMatcherpublic abstract class StaticMethodMatcher implements MethodMatcher { @Override public final boolean isRuntime() { // 静态匹配 return false; } @Override public final boolean matches(Method method, Class<?> targetClass, Object..、args) { // 抛出不支持操作异常 throw new UnsupportedOperationException("Illegal MethodMatcher usage"); }}
CacheOperationSourcePointcut 简介Spring Cache相关的Pointcut;
核心代码abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { protected CacheOperationSourcePointcut() { // 设置类过滤器为CacheOperationSource类过滤器 setClassFilter(new CacheOperationSourceClassFilter()); } @Override public boolean matches(Method method, Class<?> targetClass) { CacheOperationSource cas = getCacheOperationSource(); // 指定方法上是否存在CacheOperation return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass))); } // 获取CacheOperationSource,用于解析指定方法上的CacheOperation @Nullable protected abstract CacheOperationSource getCacheOperationSource(); // 根据CacheOperationSource.isCandidateClass实现的类过滤器 private class CacheOperationSourceClassFilter implements ClassFilter { @Override public boolean matches(Class<?> clazz) { if (CacheManager.class.isAssignableFrom(clazz)) { // 不支持CacheManager return false; } CacheOperationSource cas = getCacheOperationSource(); // CacheOperationSource不存在,或者CacheOperationSource支持该类 return (cas == null || cas.isCandidateClass(clazz)); } }}
TransactionAttributeSourcePointcut 简介Spring事务相关的Pointcut;
核心代码abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { protected TransactionAttributeSourcePointcut() { // 设置类过滤器为TransactionAttributeSourceClassFilter setClassFilter(new TransactionAttributeSourceClassFilter()); } @Override public boolean matches(Method method, Class<?> targetClass) { TransactionAttributeSource tas = getTransactionAttributeSource(); // 指定方法上是否存在TransactionAttribute return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); } // 获取TransactionAttributeSourceClassFilter,用于解析指定方法上的TransactionAttribute @Nullable protected abstract TransactionAttributeSource getTransactionAttributeSource(); // 根据TransactionAttributeSource.isCandidateClass实现的类过滤器 private class TransactionAttributeSourceClassFilter implements ClassFilter { @Override public boolean matches(Class<?> clazz) { if (TransactionalProxy.class.isAssignableFrom(clazz) || TransactionManager.class.isAssignableFrom(clazz) || PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) { return false; } TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.isCandidateClass(clazz)); } }}
NameMatchMethodPointcut 简介基于方法名称进行匹配的Pointcut,支持通配符*,如:xxx*、*xxx、*xxx*;
核心代码public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut implements Serializable { private List
使用正则表达式匹配方法全限定名称的抽象基础类,定义了匹配算法骨架,由子类实现匹配算法细节;
核心代码public abstract class AbstractRegexpMethodPointcut extends StaticMethodMatcherPointcut implements Serializable { // 匹配的正则表达式 private String[] patterns = new String[0]; // 排除的正则表达式 private String[] excludedPatterns = new String[0]; @Override public boolean matches(Method method, Class<?> targetClass) { // 是否匹配方法的全限定名称 return (matchesPattern(ClassUtils.getQualifiedMethodName(method, targetClass)) || (targetClass != method.getDeclaringClass() && matchesPattern(ClassUtils.getQualifiedMethodName(method, method.getDeclaringClass())))); } protected boolean matchesPattern(String signatureString) { // 遍历配置的匹配正则表达式 for (int i = 0; i < this.patterns.length; i++) { boolean matched = matches(signatureString, i); if (matched) { // 如果匹配上,则继续判断是否匹配排除正则表达式 for (int j = 0; j < this.excludedPatterns.length; j++) { boolean excluded = matchesExclusion(signatureString, j); if (excluded) { // 如果匹配上排除正则表达式,则认为不匹配 return false; } } // 未匹配上任何排除正则表达式,则认为匹配 return true; } } // 未匹配上任何匹配正则表达式,则认为未匹配 return false; } // 初始化匹配正则表达式 protected abstract void initPatternRepresentation(String[] patterns) throws IllegalArgumentException; // 初始化排除正则表达式 protected abstract void initExcludedPatternRepresentation(String[] patterns) throws IllegalArgumentException; // 是否匹配指定匹配正则 protected abstract boolean matches(String pattern, int patternIndex); // 是否匹配指定排除正则 protected abstract boolean matchesExclusion(String pattern, int patternIndex);}
JdkRegexpMethodPointcut 简介基于java.util.regex实现的正则表达式Pointcut;
核心代码public class JdkRegexpMethodPointcut extends AbstractRegexpMethodPointcut { // 匹配正则 private Pattern[] compiledPatterns = new Pattern[0]; // 排除正则 private Pattern[] compiledExclusionPatterns = new Pattern[0]; // 初始化匹配正则表达式 @Override protected void initPatternRepresentation(String[] patterns) throws PatternSyntaxException { this.compiledPatterns = compilePatterns(patterns); } // 初始化排除正则表达式 @Override protected void initExcludedPatternRepresentation(String[] excludedPatterns) throws PatternSyntaxException { this.compiledExclusionPatterns = compilePatterns(excludedPatterns); } // 是否匹配匹配正则 @Override protected boolean matches(String pattern, int patternIndex) { Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern); return matcher.matches(); } // 是否匹配排除正则 @Override protected boolean matchesExclusion(String candidate, int patternIndex) { Matcher matcher = this.compiledExclusionPatterns[patternIndex].matcher(candidate); return matcher.matches(); } // 编译正则表达式 private Pattern[] compilePatterns(String[] source) throws PatternSyntaxException { Pattern[] destination = new Pattern[source.length]; for (int i = 0; i < source.length; i++) { destination[i] = Pattern.compile(source[i]); } return destination; }}
AnnotationMatchingPointcut 简介匹配类上或者方法上是否有指定注解的Pointcut;
核心代码public class AnnotationMatchingPointcut implements Pointcut { private final ClassFilter classFilter; private final MethodMatcher methodMatcher; public AnnotationMatchingPointcut(Class<? extends Annotation> classAnnotationType, boolean checkInherited) { // AnnotationClassFilter类过滤器,checkInherited决定要不要寻找classAnnotationType的超类 this.classFilter = new AnnotationClassFilter(classAnnotationType, checkInherited); // 匹配任意方法 this.methodMatcher = MethodMatcher.TRUE; } public AnnotationMatchingPointcut(@Nullable Class<? extends Annotation> classAnnotationType, @Nullable Class<? extends Annotation> methodAnnotationType, boolean checkInherited) { Assert.isTrue((classAnnotationType != null || methodAnnotationType != null), "Either Class annotation type or Method annotation type needs to be specified (or both)"); // 设置类过滤器 if (classAnnotationType != null) { this.classFilter = new AnnotationClassFilter(classAnnotationType, checkInherited); } else { this.classFilter = new AnnotationCandidateClassFilter(methodAnnotationType); } // 设置方法过滤器 if (methodAnnotationType != null) { this.methodMatcher = new AnnotationMethodMatcher(methodAnnotationType, checkInherited); } else { this.methodMatcher = MethodMatcher.TRUE; } } @Override public ClassFilter getClassFilter() { return this.classFilter; } @Override public MethodMatcher getMethodMatcher() { return this.methodMatcher; } // 生成匹配类上特定注解类型的AnnotationMatchingPointcut的工厂方法 public static AnnotationMatchingPointcut forClassAnnotation(Class<? extends Annotation> annotationType) { Assert.notNull(annotationType, "Annotation type must not be null"); return new AnnotationMatchingPointcut(annotationType); } // 生成匹配方法上特定注解类型的AnnotationMatchingPointcut的工厂方法 public static AnnotationMatchingPointcut forMethodAnnotation(Class<? extends Annotation> annotationType) { Assert.notNull(annotationType, "Annotation type must not be null"); return new AnnotationMatchingPointcut(null, annotationType); } // 注解候选类过滤器,用于过滤那些无需搜索其方法的类型 private static class AnnotationCandidateClassFilter implements ClassFilter { private final Class<? extends Annotation> annotationType; AnnotationCandidateClassFilter(Class<? extends Annotation> annotationType) { this.annotationType = annotationType; } @Override public boolean matches(Class<?> clazz) { // 该clazz是否可以携带this.annotationType return AnnotationUtils.isCandidateClass(clazz, this.annotationType); } }}
AspectJexpressionPointcut 简介 Spring中使用AspectJ编织器来评估切点表达式的Pointcut实现;
切入点表达式值是一个 AspectJ 表达式,这可以引用其他切点,可以使用组合和其他操作。
由于这是由Spring AOP基于代理模型实现的,因此只支持方法执行切点;
public class AspectJexpressionPointcut extends AbstractexpressionPointcut implements ClassFilter, IntroductionAwareMethodMatcher, BeanFactoryAware { @Override public ClassFilter getClassFilter() { obtainPointcutexpression(); return this; } @Override public MethodMatcher getMethodMatcher() { obtainPointcutexpression(); return this; } private Pointcutexpression obtainPointcutexpression() { // 校验expression if (getexpression() == null) { throw new IllegalStateException("Must set property 'expression' before attempting to match"); } // this.pointcutexpression懒构建 if (this.pointcutexpression == null) { this.pointcutClassLoader = determinePointcutClassLoader(); // 构建this.pointcutexpression this.pointcutexpression = buildPointcutexpression(this.pointcutClassLoader); } return this.pointcutexpression; } // 将and/or/not转换为AspectJ逻辑运算符 private String replaceBooleanOperators(String pcExpr) { String result = StringUtils.replace(pcExpr, " and ", " && "); result = StringUtils.replace(result, " or ", " || "); result = StringUtils.replace(result, " not ", " ! "); return result; } @Override public boolean matches(Method method, Class<?> targetClass) { return matches(method, targetClass, false); } @Override public boolean isRuntime() { return obtainPointcutexpression().mayNeedDynamicTest(); } @Override public boolean matches(Method method, Class<?> targetClass, Object..、args) { obtainPointcutexpression(); ShadowMatch shadowMatch = getTargetShadowMatch(method, targetClass); ProxyMethodInvocation pmi = null; Object targetObject = null; Object thisObject = null; try { MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation(); targetObject = mi.getThis(); if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } pmi = (ProxyMethodInvocation) mi; thisObject = pmi.getProxy(); } catch (IllegalStateException ex) { // log } try { JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args); if (pmi != null && thisObject != null) { // there is a current invocation RuntimeTestWalker originalMethodResidueTest = getRuntimeTestWalker(getShadowMatch(method, method)); if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) { return false; } if (joinPointMatch.matches()) { bindParameters(pmi, joinPointMatch); } } return joinPointMatch.matches(); } catch (Throwable ex) { // log return false; } }}