概述
经过aop切面表达式解析(一)和aop切面表达式解析(二)分析,我们己经知道表达式解析成相应和 PatternPointcut,就如下例中,切面表达式execution(* com.spring_101_200.test_111_120.test_117_excution.excution1..(…))是如何匹配到MyService类中的service方法的呢?带着疑问,我们今天来继续跟进源码。
AspectJTest
@Aspect @Configuration public class AspectJTest { @Before("execution(* com.spring_101_200.test_111_120.test_117_excution.excution1.*.*(..))") public void beforeTest() { System.out.println("beforeTest"); } }
今天我们主要分析Spring 是如何解析 execution(* com.spring_101_200.test_111_120.test_117_excution.excution1..(…)) 表达式。
MyService.java
@Service public class MyService { public void service() { System.out.println("serivce"); } }
spring_117_excution1.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <context:component-scan base-package="com.spring_101_200.test_111_120.test_117_excution.excution1"></context:component-scan> </beans>
测试:
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_101_200/config_111_120/spring117_excution/spring_117_excution1.xml"); MyService myService = ac.getBean(MyService.class); myService.service(); }
结果输出:
经过上面的示例,现在,我们来进行源码分析。
AopUtil.java
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); if (!pc.getClassFilter().matches(targetClass)) { return false; } //获取切面表达式的方法匹配 MethodMatcher methodMatcher = pc.getMethodMatcher(); IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } //获取当前类及祖先类所有接口 Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); for (Class<?> clazz : classes) { Method[] methods = clazz.getMethods(); for (Method method : methods) { if ((introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) || methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
只要目标类中任意方法被匹配,将返回 true,表示该类是可以设置为代理的。
AspectJExpressionPointcut.java
public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) { //检测切面表达式是否解析完成 checkReadyToMatch(); //因为存在继承,实现接口,所以,目标类调用的方法不一定是自己的类方法,可能是继承而得来的。 //因此,这里,获取方法的实际所在类的方法,比如 A 类继承 B类,调用 B 类的 b 方法, //目标方法即 :B.b()方法,而不是 A.b()方法 Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); //获取影子匹配 ShadowMatch shadowMatch = getShadowMatch(targetMethod, method); //只要返回 true ,则表示该类可创建代理 if (shadowMatch.alwaysMatches()) { return true; } else if (shadowMatch.neverMatches()) { return false; } else { if (beanHasIntroductions) { return true; } RuntimeTestWalker walker = getRuntimeTestWalker(shadowMatch); return (!walker.testsSubtypeSensitiveVars() || walker.testTargetInstanceOfResidue(targetClass)); } }
AspectJExpressionPointcut.java
private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) { //从缓存中获取 ShadowMatch shadowMatch = this.shadowMatchCache.get(targetMethod); if (shadowMatch == null) { synchronized (this.shadowMatchCache) { //如果缓存中不存在,再次确认一遍 PointcutExpression fallbackExpression = null; Method methodToMatch = targetMethod; shadowMatch = this.shadowMatchCache.get(targetMethod); if (shadowMatch == null) { try { //开始匹配方法表达式 shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch); } catch (ReflectionWorldException ex) { try { fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass()); if (fallbackExpression != null) { shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch); } } catch (ReflectionWorldException ex2) { fallbackExpression = null; } } if (shadowMatch == null && targetMethod != originalMethod) { methodToMatch = originalMethod; try { shadowMatch = this.pointcutExpression.matchesMethodExecution(methodToMatch); } catch (ReflectionWorldException ex3) { try { fallbackExpression = getFallbackPointcutExpression(methodToMatch.getDeclaringClass()); if (fallbackExpression != null) { shadowMatch = fallbackExpression.matchesMethodExecution(methodToMatch); } } catch (ReflectionWorldException ex4) { fallbackExpression = null; } } } if (shadowMatch == null) { shadowMatch = new ShadowMatchImpl(org.aspectj.util.FuzzyBoolean.NO, null, null, null); } else if (shadowMatch.maybeMatches() && fallbackExpression != null) { shadowMatch = new DefensiveShadowMatch(shadowMatch, fallbackExpression.matchesMethodExecution(methodToMatch)); } this.shadowMatchCache.put(targetMethod, shadowMatch); } } } return shadowMatch; }
PointcutExpressionImpl.java
public ShadowMatch matchesMethodExecution(Method aMethod) { ShadowMatch match = matchesExecution(aMethod); if (MATCH_INFO && match.maybeMatches()) { System.out.println("MATCHINFO: method execution match on '" + aMethod + "' for '" + this.expression + "': " + (match.alwaysMatches() ? "YES" : "MAYBE")); } return match; }
PointcutExpressionImpl.java
private ShadowMatch matchesExecution(Member aMember) { Shadow s = ReflectionShadow.makeExecutionShadow(world, aMember, this.matchContext); ShadowMatchImpl sm = getShadowMatch(s); sm.setSubject(aMember); sm.setWithinCode(null); sm.setWithinType(aMember.getDeclaringClass()); return sm; }
ReflectionShadow.java
public static Shadow makeExecutionShadow(World inWorld, java.lang.reflect.Member forMethod, MatchingContext withContext) { Kind kind = (forMethod instanceof Method) ? Shadow.MethodExecution : Shadow.ConstructorExecution; Member signature = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(forMethod, inWorld); ResolvedType enclosingType = signature.getDeclaringType().resolve(inWorld); return new ReflectionShadow(inWorld, kind, signature, null, enclosingType, null, withContext); }
ReflectionBasedReferenceTypeDelegateFactory.java
public static ResolvedMember createResolvedMember(Member reflectMember, World inWorld) { if (reflectMember instanceof Method) { return createResolvedMethod((Method) reflectMember, inWorld); } else if (reflectMember instanceof Constructor) { return createResolvedConstructor((Constructor) reflectMember, inWorld); } else { return createResolvedField((Field) reflectMember, inWorld); } }
public static ResolvedMember createResolvedMethod(Method aMethod, World inWorld) { ReflectionBasedResolvedMemberImpl ret = new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD, toResolvedType(aMethod.getDeclaringClass(), (IReflectionWorld) inWorld), aMethod.getModifiers(), toResolvedType( aMethod.getReturnType(), (IReflectionWorld) inWorld), aMethod.getName(), toResolvedTypeArray( aMethod.getParameterTypes(), inWorld), toResolvedTypeArray(aMethod.getExceptionTypes(), inWorld), aMethod); if (inWorld instanceof IReflectionWorld) { ret.setAnnotationFinder(((IReflectionWorld) inWorld).getAnnotationFinder()); } //创建Java15GenericSignatureInformationProvider对象 ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); return ret; }
PointcutExpressionImpl.java
private ShadowMatchImpl getShadowMatch(Shadow forShadow) { //对表达式进行匹配 org.aspectj.util.FuzzyBoolean match = pointcut.match(forShadow); Test residueTest = Literal.TRUE; ExposedState state = getExposedState(); //如果返回的值是模棱两可的,进一步确认 if (match.maybeTrue()) { //在写第六篇博客时,发现这一行代码很重要,因此回头来补这行代码解析 residueTest = pointcut.findResidue(forShadow, state); } ShadowMatchImpl sm = new ShadowMatchImpl(match, residueTest, state, parameters); sm.setMatchingContext(this.matchContext); return sm; }
Pointcut.java
public final FuzzyBoolean match(Shadow shadow) { //每个Shadow对象的 shadowId 不一样,每 new 一个,shadowId + 1,如果当前 shadow 是最后一个了,直接返回 if (shadow.shadowId == lastMatchedShadowId) { return lastMatchedShadowResult; } FuzzyBoolean ret; if (shadow.getKind().isSet(couldMatchKinds())) { //开始匹配 ret = matchInternal(shadow); } else { ret = FuzzyBoolean.NO; } lastMatchedShadowId = shadow.shadowId; lastMatchedShadowResult = ret; return ret; }
KindedPointcut.java
protected FuzzyBoolean matchInternal(Shadow shadow) { //目标方法类型和切面表达式的方法类型是否匹配 if (shadow.getKind() != kind) { return FuzzyBoolean.NO; } //@Before("lock(* *(java.util.Map<com..Model, com..Model>, ..))") //如果切面表达式的 kind 是 lock,方法的类型也是 lock,直接返回 YES if (shadow.getKind() == Shadow.SynchronizationLock && kind == Shadow.SynchronizationLock) { return FuzzyBoolean.YES; } //@Before("unlock(* *(java.util.Map<com..Model, com..Model>, ..))") //如果切面表达式配置了 unlock,并且方法的类型也是 unlock,直接返回 YES if (shadow.getKind() == Shadow.SynchronizationUnlock && kind == Shadow.SynchronizationUnlock) { return FuzzyBoolean.YES; } //切面表达式和方法匹配 if (!signature.matches(shadow.getMatchingSignature(), shadow.getIWorld(), this.kind == Shadow.MethodCall)) { if (kind == Shadow.MethodCall) { //如果上面进行匹配返回false,并且方法类型是 method-call warnOnConfusingSig(shadow); } return FuzzyBoolean.NO; } return FuzzyBoolean.YES; }
SignaturePattern.java
public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) { //如果目标方法签名为空,直接返回 false if (joinPointSignature == null) { return false; } //如果目标方法的类型和切面表达式配置的类型不相等,返回 false if (kind != joinPointSignature.getKind()) { return false; } //如果切面表达式是ADVICE类型,直接返回 true if (kind == Member.ADVICE) { return true; } boolean subjectMatch = true; //是否需要进行方法上注解匹配 boolean wantsAnnotationMatch = wantToMatchAnnotationPattern(); JoinPointSignatureIterator candidateMatches = joinPointSignature.getJoinPointSignatures(world); while (candidateMatches.hasNext()) { JoinPointSignature aSig = candidateMatches.next(); //精确匹配 FuzzyBoolean matchResult = matchesExactly(aSig, world, allowBridgeMethods, subjectMatch); if (matchResult.alwaysTrue()) { return true; } else if (matchResult.alwaysFalse()) { return false; } //如果返回的是 MAYBE,则需要去看该方法的修饰符,注解,和 throws 异常 subjectMatch = false; if (wantsAnnotationMatch) { return false; } } return false; }
private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods, boolean subjectMatch) { //如果方法是桥接方法,返回 MAYBE if (aMember.isBridgeMethod() && !allowBridgeMethods) { return FuzzyBoolean.MAYBE; } //如果方法的修饰符不匹配,返回 NO if (subjectMatch && !modifiers.matches(aMember.getModifiers())) { return FuzzyBoolean.NO; } FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES; if (kind == Member.STATIC_INITIALIZATION) { //如果类型是静态初始化类型 matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld); } else if (kind == Member.FIELD) { //如果类型是属性 matchesIgnoringAnnotations = matchesExactlyField(aMember, inAWorld); } else if (kind == Member.METHOD) { //如果类型是方法 matchesIgnoringAnnotations = matchesExactlyMethod(aMember, inAWorld, subjectMatch); } else if (kind == Member.CONSTRUCTOR) { //如果类型是构造方法 matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld); } if (matchesIgnoringAnnotations.alwaysFalse()) { return FuzzyBoolean.NO; } //进行方法注解匹配 if (subjectMatch) { // The annotations must match if specified if (!matchesAnnotations(aMember, inAWorld).alwaysTrue()) { return FuzzyBoolean.NO; } else { return matchesIgnoringAnnotations; } } else { //如果注解类型是任意类型 if (annotationPattern instanceof AnyAnnotationTypePattern) { return matchesIgnoringAnnotations; } else { return FuzzyBoolean.NO; } } }
private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) { //如果方法参数不匹配,返回 NO if (parametersCannotMatch(aMethod)) { return FuzzyBoolean.NO; } //如果方法的名称不匹配,返回 NO if (!name.matches(aMethod.getName())) { return FuzzyBoolean.NO; } //如果切面表达式配置的方法抛出异常不匹配,返回 NO if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) { return FuzzyBoolean.NO; } //如果包名和类名匹配不是*,则对第一项进行匹配 if (!declaringType.isStar()) { if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) { return FuzzyBoolean.MAYBE; } } //如果返回值类型不是*,则对返回值类型进行匹配 if (!returnType.isStar()) { boolean b = returnType.isBangVoid(); if (b) { //如果表达式配置的匹配类型不是 void类型,而目标方法的类型是 Void 类型,则返回 NO String s = aMethod.getReturnType().getSignature(); if (s.length() == 1 && s.charAt(0) == 'V') { return FuzzyBoolean.NO; } } else { //如果表达式配置的类型是 void 类型,而目标方法的类型不是 void类型,返回 NO if (returnType.isVoid()) { String s = aMethod.getReturnType().getSignature(); if (s.length() != 1 || s.charAt(0) != 'V') { return FuzzyBoolean.NO; } } else { //如果表达式配置的方法返回值类型和目标方法返回值类型都不为空。则进行相关匹配,这下面考虑到泛型 if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) { if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) { return FuzzyBoolean.MAYBE; } } } } } //如果表达式方法参数类型只有一个参数,并且是 .. ,则直接返回 YES if (parameterTypes.size() == 1 && parameterTypes.get(0).isEllipsis()) { return FuzzyBoolean.YES; } //如果表达式配置的方法参数长度不等于目标方法参数个数时,返回 NO if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) { return FuzzyBoolean.NO; } ResolvableTypeList rtl = new ResolvableTypeList(world, aMethod.getParameterTypes()); //如果方法参数上有注解,则对每个方法参数上的注解进行获取 ResolvedType[][] parameterAnnotationTypes = null; if (isMatchingParameterAnnotations()) { parameterAnnotationTypes = aMethod.getParameterAnnotationTypes(); if (parameterAnnotationTypes != null && parameterAnnotationTypes.length == 0) { parameterAnnotationTypes = null; } } //方法参数类型匹配 if (!parameterTypes.matches(rtl, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) { //方法参数类型匹配 //如:表达式是这样配置 @Before("execution(* *(java.util.Map<com..Model, com..Model>, ..))") // 将对(java.util.Map<com..Model, com..Model>, ..)中的每一项进行匹配,首先类型 java.util.Map, // 再是泛型com..Model 进行匹配,以及方法参数个数进行匹配 if (!parameterTypes.matches(new ResolvableTypeList(world, aMethod.getGenericParameterTypes()), TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) { return FuzzyBoolean.MAYBE; } } //如果可变参数类型 if (!matchesVarArgs(aMethod, world)) { return FuzzyBoolean.MAYBE; } return FuzzyBoolean.YES; }
SignaturePattern.java
private boolean parametersCannotMatch(JoinPointSignature methodJoinpoint) { //如果目标方法是可变参数,直接返回 false if (methodJoinpoint.isVarargsMethod()) { return false; } //表达式中配置方法参数类型个数 int patternParameterCount = parameterTypes.size(); //如果表达式中方法参数个数为0或者没有配置省略号(..) if (patternParameterCount == 0 || parameterTypes.ellipsisCount == 0) { boolean equalCount = patternParameterCount == methodJoinpoint.getParameterTypes().length; //如果表达式中配置方法参数个数为0,但是目标方法参数个数不为0,返回 true if (patternParameterCount == 0 && !equalCount) { return true; } //如果表达式中配置省略号个数为0 并且目标方法参数不等于表达式中配置参数个数 if (parameterTypes.ellipsisCount == 0 && !equalCount) { //表达式中参数个数大于0,并且表达式中最后一个参数是可变参数,返回 false,匹配继续。 if (patternParameterCount > 0 && parameterTypes.get(patternParameterCount - 1).isVarArgs()) { return false; } return true; } } return false; }
在这个方法中,我们要注意的一点就是,返回 false,表示匹配继续,返回 true,表示匹配结束,表达式与方法不匹配。
TypePattern.java
public boolean matchesStatically(ResolvedType type) { if (includeSubtypes) { //如果表达式中包含+号,也就是包含子类型 return matchesSubtypes(type); } else { return matchesExactly(type); } }
WildTypePattern.java
protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) { String targetTypeName = type.getName(); //确保注解模式己经解析 annotationPattern.resolve(type.getWorld()); //方法名称匹配 return matchesExactlyByName(targetTypeName, type.isAnonymous(), type.isNested()) //方法参数类型匹配 && matchesParameters(type, STATIC) //界线匹配 && matchesBounds(type, STATIC) //注解匹配 && annotationPattern.matches(annotatedType, type.temporaryAnnotationTypes).alwaysTrue(); }
private boolean matchesExactlyByName(String targetTypeName, boolean isAnonymous, boolean isNested) { //如果目标类型名称中有泛型 if (targetTypeName.indexOf('<') != -1) { targetTypeName = targetTypeName.substring(0, targetTypeName.indexOf('<')); } //如果目标类型名称以?开头 if (targetTypeName.startsWith(GENERIC_WILDCARD_CHARACTER)) { targetTypeName = GENERIC_WILDCARD_CHARACTER; } if (knownMatches == null && importedPrefixes == null) { return innerMatchesExactly(targetTypeName, isAnonymous, isNested); } //如果配置的是* if (isNamePatternStar()) { int numDimensionsInTargetType = 0; //对于数组类型匹配 if (dim > 0) { int index; while ((index = targetTypeName.indexOf('[')) != -1) { numDimensionsInTargetType++; targetTypeName = targetTypeName.substring(index + 1); } //如果表达式中配置的数组维数和目标方法中数组维数不一致,返回 false if (numDimensionsInTargetType == dim) { return true; } else { return false; } } } if (namePatterns.length == 1) { //匿名类型 if (isAnonymous) { return false; } for (int i = 0, len = knownMatches.length; i < len; i++) { if (knownMatches[i].equals(targetTypeName)) { return true; } } } else { for (int i = 0, len = knownMatches.length; i < len; i++) { String knownMatch = knownMatches[i]; //内部类相关处理 if (targetTypeName.startsWith(knownMatch) && targetTypeName.length() > knownMatch.length() && targetTypeName.charAt(knownMatch.length()) == '$') { int pos = lastIndexOfDotOrDollar(knownMatch); if (innerMatchesExactly(targetTypeName.substring(pos + 1), isAnonymous, isNested)) { return true; } } } } for (int i = 0, len = importedPrefixes.length; i < len; i++) { String prefix = importedPrefixes[i]; //如果以 java.lang.开头 if (targetTypeName.startsWith(prefix)) { if (innerMatchesExactly(targetTypeName.substring(prefix.length()), isAnonymous, isNested)) { return true; } } } return innerMatchesExactly(targetTypeName, isAnonymous, isNested); }
private boolean innerMatchesExactly(String s, boolean isAnonymous, boolean convertDollar /* isNested */) { //将表达式的包名和类名分割成 List 字符数组 List<char[]> ret = new ArrayList<char[]>(); int startIndex = 0; while (true) { int breakIndex = s.indexOf('.', startIndex); // what about / if (convertDollar && (breakIndex == -1)) { breakIndex = s.indexOf('$', startIndex); // we treat $ like . here } if (breakIndex == -1) { break; } char[] name = s.substring(startIndex, breakIndex).toCharArray(); ret.add(name); startIndex = breakIndex + 1; } ret.add(s.substring(startIndex).toCharArray()); int namesLength = ret.size(); int patternsLength = namePatterns.length; int namesIndex = 0; int patternsIndex = 0; if ((!namePatterns[patternsLength - 1].isAny()) && isAnonymous) { return false; } //如果名称和类名表达式中没有省略号【..】 if (ellipsisCount == 0) { if (namesLength != patternsLength) { return false; } while (patternsIndex < patternsLength) { //每个字符逐个匹配,如果匹配不成功,返回 false if (!namePatterns[patternsIndex++].matches(ret.get(namesIndex++))) { return false; } } return true; } else if (ellipsisCount == 1) {////如果包名类型表达式中有一个省略号 if (namesLength < patternsLength - 1) { return false; } while (patternsIndex < patternsLength) { NamePattern p = namePatterns[patternsIndex++]; if (p == NamePattern.ELLIPSIS) { //跳过中间省略号 namesIndex = namesLength - (patternsLength - patternsIndex); } else { //省略号前和省略号后逐个匹配,匹配不成功,返回 false。 if (!p.matches(ret.get(namesIndex++))) { return false; } } } return true; } else { //如果有多个省略号的情况 boolean b = outOfStar(namePatterns, ret.toArray(new char[ret.size()][]), 0, 0, patternsLength - ellipsisCount, namesLength, ellipsisCount); return b; } }
public boolean matches(char[] a2) { char[] a1 = pattern; int len1 = a1.length; int len2 = a2.length; //如果字符数组中一个*都没有的情况 if (starCount == 0) { //两字符串长度不相等,则肯定不匹配 if (len1 != len2) { return false; } //否则,一个一个进行匹配 for (int i = 0; i < len1; i++) { if (a1[i] != a2[i]) { return false; } } return true; } else if (starCount == 1) { //如果表达式中有一个*号的情况 if (len1 == 1) { return true; } //如果表达式中有*号,而且长度还大于目标方法字符数组,返回 false if (len1 > len2 + 1) { return false; } int i2 = 0; for (int i1 = 0; i1 < len1; i1++) { char c1 = a1[i1]; //*吃掉多余字符 if (c1 == '*') { i2 = len2 - (len1 - (i1 + 1)); } else if (c1 != a2[i2++]) {//没有遇到*号时,逐个进行匹配,字符不相等,返回 false return false; } } return true; } else { //表达式中有多个*号的情况处理 boolean b = outOfStar(a1, a2, 0, 0, len1 - starCount, len2, starCount); return b; } }
在进行动态代理调用拦截器链时,发现下面的这个代码非常重要,因此,补一下这一块代码的解析,不过这一块代码以这个表达式为基础execution(* com.spring_1_100.test_61_70.test65_2..(…)) && args(x,y),使用的代码在 github 的 test65_2包下。
Pointcut.java
public final Test findResidue(Shadow shadow, ExposedState state) { //如果当前 shadow 己经被匹配过,将不再匹配 Test ret = findResidueInternal(shadow, state); lastMatchedShadowId = shadow.shadowId; return ret; }
AndPointcut.java
protected Test findResidueInternal(Shadow shadow, ExposedState state) { //根据表达式,execution(* com.spring_1_100.test_61_70.test65_4.*.*(..)) && args(x,y) //left 是execution(* com.spring_1_100.test_61_70.test65_4.*.*(..)) 表达式构建的 shadow //right是args(x,y)表达式构建的 shadow,左边表达式己经匹配过了,因此不再分析,右边表达式解析出来的PointCut //类型是ArgsPointcut类,因此,其提供了自己findResidueInternal()方法。 return Test.makeAnd(left.findResidue(shadow, state), right.findResidue(shadow, state)); }
public final Test findResidue(Shadow shadow, ExposedState state) { Test ret = findResidueInternal(shadow, state); lastMatchedShadowId = shadow.shadowId; return ret; }
ArgsPointcut.java
protected Test findResidueInternal(Shadow shadow, ExposedState state) { //获取当前方法参数的ResolvedType[]类型 ResolvedType[] argsToMatch = getArgumentsToMatchAgainst(shadow); //方法参数个数匹配,以及方法参数类型匹配,不匹配,返回 false if (arguments.matches(argsToMatch, TypePattern.DYNAMIC).alwaysFalse()) { return Literal.FALSE; } //表达式中方法参数配置省略号个数 int ellipsisCount = arguments.ellipsisCount; if (ellipsisCount == 0) {//没有配置省略号 return findResidueNoEllipsis(shadow, state, arguments.getTypePatterns()); } else if (ellipsisCount == 1) {//配置1个省略号 TypePattern[] patternsWithEllipsis = arguments.getTypePatterns(); TypePattern[] patternsWithoutEllipsis = new TypePattern[argsToMatch.length]; int lenWithEllipsis = patternsWithEllipsis.length; int lenWithoutEllipsis = patternsWithoutEllipsis.length; // l1+1 >= l0 int indexWithEllipsis = 0; int indexWithoutEllipsis = 0; while (indexWithoutEllipsis < lenWithoutEllipsis) { TypePattern p = patternsWithEllipsis[indexWithEllipsis++]; if (p == TypePattern.ELLIPSIS) { int newLenWithoutEllipsis = lenWithoutEllipsis - (lenWithEllipsis - indexWithEllipsis); while (indexWithoutEllipsis < newLenWithoutEllipsis) { patternsWithoutEllipsis[indexWithoutEllipsis++] = TypePattern.ANY; } } else { patternsWithoutEllipsis[indexWithoutEllipsis++] = p; } } return findResidueNoEllipsis(shadow, state, patternsWithoutEllipsis); } else { throw new BCException("unimplemented"); } }
private Test findResidueNoEllipsis(Shadow shadow, ExposedState state, TypePattern[] patterns) { ResolvedType[] argumentsToMatchAgainst = getArgumentsToMatchAgainst(shadow); int len = argumentsToMatchAgainst.length; //如果方法参数个数和args()中目标方法配置参数个数不匹配,返回 false if (patterns.length != len) { return Literal.FALSE; } Test ret = Literal.TRUE; for (int i = 0; i < len; i++) { UnresolvedType argType = shadow.getGenericArgTypes()[i]; TypePattern type = patterns[i]; ResolvedType argRTX = shadow.getIWorld().resolve(argType, true); if (!(type instanceof BindingTypePattern)) { //如果表达式解析出来的类型非BindingTypePattern类型 if (argRTX.isMissing()) { shadow.getIWorld().getLint().cantFindType.signal(new String[] { WeaverMessages.format( WeaverMessages.CANT_FIND_TYPE_ARG_TYPE, argType.getName()) }, shadow.getSourceLocation(), new ISourceLocation[] { getSourceLocation() }); } if (type.matchesInstanceof(argRTX).alwaysTrue()) { continue; } } World world = shadow.getIWorld(); ResolvedType typeToExpose = type.getExactType().resolve(world); //如果表达式中配置类型是基本数据类型 if (typeToExpose.isParameterizedType()) { boolean inDoubt = (type.matchesInstanceof(argRTX) == FuzzyBoolean.MAYBE); if (inDoubt && world.getLint().uncheckedArgument.isEnabled()) { String uncheckedMatchWith = typeToExpose.getSimpleBaseName(); if (argRTX.isParameterizedType() && (argRTX.getRawType() == typeToExpose.getRawType())) { uncheckedMatchWith = argRTX.getSimpleName(); } if (!isUncheckedArgumentWarningSuppressed()) { world.getLint().uncheckedArgument.signal(new String[] { typeToExpose.getSimpleName(), uncheckedMatchWith, typeToExpose.getSimpleBaseName(), shadow.toResolvedString(world) }, getSourceLocation(), new ISourceLocation[] { shadow.getSourceLocation() }); } } } ret = Test.makeAnd(ret, exposeStateForVar(shadow.getArgVar(i), type, state, shadow.getIWorld())); } return ret; }
NameBindingPointcut.java
protected Test exposeStateForVar(Var var,TypePattern type, ExposedState state, World world) { if (type instanceof BindingTypePattern) { BindingTypePattern b = (BindingTypePattern)type; //设置目标方法的实际类型 state.set(b.getFormalIndex(), var); } ResolvedType myType = type.getExactType().resolve(world); //如果是基本数据类型 if (myType.isParameterizedType()) { myType = (ResolvedType) myType.getRawType(); } //判断目标方法参数的实际类型与表达式所配置的类型是否一致 return Test.makeInstanceof(var, myType.resolve(world)); }
Test.java
public static Test makeInstanceof(Var v, ResolvedType ty) { if (ty.equals(ResolvedType.OBJECT)) return Literal.TRUE; Test e; if (ty.isAssignableFrom(v.getType())) e = Literal.TRUE; else if (! ty.isCoerceableFrom(v.getType())) e = Literal.FALSE; else e = new Instanceof(v, ty); return e; }
最终将返回的 Test 对象保存到ShadowMatchImpl.residualTest属性中。
流程:
1)canApply() :是否符合切面条件 1)getClassFilter().matches(): 类是否匹配 2)methodMatcher.matches(): 方法是否匹配 1) checkReadyToMatch(): 简单的较验 2) getMostSpecificMethod(): 获取当前拦截类的方法 1)getMostSpecificMethod() :当如果调用的当前方法不是自己类的方法,是父类中继承来的方法,将匹配到父类中方法。 1)getMethod0() :获取方法。 1)privateGetMethodRecursive(): 递归获取方法 1)privateGetDeclaredMethods() : 获取该类或接口的所有的方法 1)searchMethods(): 搜索合适的方法 2)getSuperclass():如果本类中没有搜索到匹配的方法,到父类中查找 1)getMethod0():递归调用父类的获取方法 3) getInterfaces(): 如果本类或者父类中没有找到,获取该类的所有接口,这种情况,只有在 jdk1.8中才支持,在接口中定义默认方法。 1)getMethod0(): 递归获取接口中合适的方法。 3)getShadowMatch():获取ShadowMatch匹配 1)matchesMethodExecution():匹配方法执行 1)matchesExecution(): 匹配执行 1)makeExecutionShadow(): 1)createResolvedMember(): 创建Member 1)createResolvedMethod():创建ResolvedMember 1)new ReflectionBasedResolvedMemberImpl(): 创建反射 Member 类 1) this.kind: 初始化当前类型为METHON 2) this.declaringType:当前方法类型com.spring_101_200.test_111_120.test_117_excution.excution1.MyService 3) this.modifiers: 当前方法修饰符 4) this.returnType: 设置返回值类型 5) this.name:方法名称 6) this.parameterTypes:设置方法参数类型 7) this.erasedSignature:方法的返回值的字节码常量池的表示方法 ,如()V 8) this.checkedExceptions:设置异常较验。 9) this.reflectMember: 设置方法的 Member 类型 10) this.annotationFinder:设置注解发现器Java15AnnotationFinder 11) setGenericSignatureInformationProvider():设置Java15GenericSignatureInformationProvider 2)new ReflectionShadow():创建ReflectionShadow 2)getShadowMatch(): 获取匹配的实现类 1)match(): 开始匹配 1)matchInternal():真正匹配 1)matches(): 是否匹配signature 1)matchesExactly(): 精确匹配 1)modifiers.matches(): 方法修饰符匹配,如果不匹配,返回 false 。 2)matchesExactlyMethod(): 方法精确匹配 1) parametersCannotMatch(): 参数匹配。 2) name.matches():方法名称匹配。 3) throwsPattern.matches(): 异常类型匹配。不匹配返回 NO 4)declaringType.matchesStatically():包,类,匹配。 1)matchesExactly(): do 包,类匹配 1)matchesExactlyByName(): 通过包名,类名,方法名匹配。 1)innerMatchesExactly():具体匹配 1)namePatterns[patternsIndex++].matches(ret.get(namesIndex++)) :匹配每一个包名,类名,以及方法名。 2)matchesParameters(): 方法参数类型匹配。 3)matchesBounds(): 有界引用类型匹配。 4)annotationPattern.matches() :方法注解类型匹配。 5)returnType.matchesStatically():返回值类型匹配 6)parameterTypes.count() : 参数个数匹配 2)匹配成功返回 true,匹配失败返回 false。
到这里,我们己经解析完成,来总结一下,其实切面表达式的匹配过程非常的繁琐,但是又每一步必不可少,切面表达式在解析时就确定当前表达式是哪个 PointCut,在匹配时,就调用哪一个 PointCut的 matches 方法。这种策略模式,将复杂表达式清淅的在规律的分布在Spring代码的各个角落。从而实现了表达式的解析和匹配。下面我们来具体的分析一下整个匹配流程。
1.根据目标方法找到最合适的方法,假如切面表达式限制只能 com.a 包下的方法才被拦截,而此时com.a.A继承 com.b.B 类 com.b.B 中有 test()方法,此时调用com.a.A.test()方法,因为 test()方法是 A 类从 B 类中继承而来,方法属于 com.b包下的方法,因此,而此时切面只拦截 com.a 包下的所有方法,因此,此时调用 com.a.A().test()方法,将不被拦截。 2.封装ReflectionShadow对象,将从切面表达式中解析出来的方法修饰,返回值,方法注解,包名类名,方法名,方法参数类 型,方法参数个数,方法注解类型,等等,封装到ReflectionShadow对象。 3.目标方法和切面表达式匹配:将目标方法的每一项和方法的每一项进行匹配,只要匹配失败,返回 NO。
在具体去分析某个具体的 Spring 示例时,会觉得 Spring 的博大精深,大到架构,小到字符串匹配,都透露着高明之处,而且无论你怎样复杂的表达式,都会被解析完成,因为里面用了大量的递归调用,相当于孙猴子无论如何都跳不出如来的五指山一样,非常的值得学习,有兴趣的小伙伴还是自己打断点,自行研究一下吧。相信你有意想不到的收获。如果你专心看完这篇博客时,那来思考一下下面的问题?
思考?
User.java
@MyAnnotation public class User { }
Model.java
public class Model implements Serializable { }
MyAnnotation.java
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD,ElementType.PARAMETER,ElementType.FIELD}) @Documented public @interface MyAnnotation { String value() default ""; }
UserService.java
public interface UserService { void testModel(Map
UserServiceImpl.java
@Service public class UserServiceImpl implements UserService { @Override public void testModel(Map<Model, Model> modelMap, String a) { System.out.println("testModel"); } @Override public void testModel1(String a, Map<Model, Model> modelMap) { System.out.println("testModel1"); } @Override public void testModel2(Map modelMap, String a) { System.out.println("testModel2"); } }
AspectJTest.java
public class AspectJTest { @Before("execution(* *(@com..MyAnnotation (@com..MyService *),@com..MyAnnotation (@com..MyService *)))") public void beforeTest() { System.out.println("beforeTest"); } }
测试:
public void test17() throws Exception { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring_101_200/config_111_120/spring117_excution/spring_117_excution17.xml"); System.out.println("============================"); UserService userService = ac.getBean(UserService.class); userService.getUserHomeWork(new User(), new User()); System.out.println("============================="); userService.getUserHomeInfo(new User(), new User()); System.out.println("============================="); userService.getModelInfo(new Model(), new Model()); }
结果?
感兴趣的小伙伴,去研究一下,为什么是这样的输出结果?
本文的github地址是
https://github.com/quyixiao/spring_tiny/tree/master/src/main/java/com/spring_101_200/test_111_120/test_117_excution/excution1
最后
以上就是无聊雪碧为你收集整理的Spring源码深度解析(郝佳)-学习-源码解析-aop切面表达式匹配(四)的全部内容,希望文章能够帮你解决Spring源码深度解析(郝佳)-学习-源码解析-aop切面表达式匹配(四)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复