欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

SpringAOP基础组件Pointcut

时间:2023-07-07
相关阅读

Spring AOP基础组件 AdviceSpring AOP基础组件 Advisor 简介

定义了切面的匹配点,即哪些类的哪些方法;在Spring AOP中匹配点主要是class(ClassFilter)和method(MethodFilter)两个维度;

源码 Pointcut

public interface Pointcut { // 类过滤器,用于匹配类 ClassFilter getClassFilter(); // 方法匹配器,用于匹配方法 MethodMatcher getMethodMatcher(); // 默认匹配所有类的所有方法 Pointcut TRUE = TruePointcut.INSTANCE;}

TruePointcut

final 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;}

TrueClassFilter

final class TrueClassFilter implements ClassFilter, Serializable { public static final TrueClassFilter INSTANCE = new TrueClassFilter(); // 确保单例 private TrueClassFilter() { } @Override public boolean matches(Class<?> clazz) { // 全匹配 return true; }}

MethodMatcher

public interface MethodMatcher { // 是否静态地匹配指定类的指定方法 boolean matches(Method method, Class<?> targetClass); // 是否动态匹配 boolean isRuntime(); // 是否动态地匹配指定类的指定方法 boolean matches(Method method, Class<?> targetClass, Object..、args); // 匹配任意方法的示例 MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;}

TrueMethodMatcher

final 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; }}

DynamicMethodMatcher

public 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; }}

StaticMethodMatcher

public 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 mappedNames = new ArrayList<>(); @Override public boolean matches(Method method, Class<?> targetClass) { // 遍历已配置的映射名称集合 for (String mappedName : this.mappedNames) { if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) { // 指定的方法名称匹配上映射的名称则认为匹配 return true; } } return false; } protected boolean isMatch(String methodName, String mappedName) { // 判断指定的方法名称是否正则匹配映射名称,支持通配符* return PatternMatchUtils.simpleMatch(mappedName, methodName); }}

AbstractRegexpMethodPointcut 简介

使用正则表达式匹配方法全限定名称的抽象基础类,定义了匹配算法骨架,由子类实现匹配算法细节;

核心代码

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; } }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。