当前位置: 首页 > article >正文

AspectJ 中类型的绑定

我们知道,在 AspectJ 中配置切点表达时,需配置全限定性类名,但对于 java.lang.String 可以简化为 String,直接配置,这是怎么实现的呢?这就涉及到了 AspectJ 中的类型绑定机制。

示例一

"execution(* *..UserServiceImpl.doSome(String...,int))"

我们知道,在 Java 的语法中,可变参数只能放在形参的最后,并且每个方法只能有一个可变参数,但是在 AspectJ 的切入点表达式解析规则中,上面的配置是可以解析的。

参数解析

在 org.aspectj.weaver.patterns.PatternParser#parseMethodOrConstructorSignaturePattern 方法中,会执行 parseArgumentsPattern,解析得到参数的匹配模式。

// 解析参数类型时,以 "," 作为类型分割,每个类型单独解析
public TypePatternList parseArgumentsPattern(boolean parameterAnnotationsPossible) {
	List<TypePattern> patterns = new ArrayList<>();
	eat("(");

	// ()
	if (maybeEat(")")) {
		return new TypePatternList();
	}

	do {
		if (maybeEat(".")) { // ..
			eat(".");
			patterns.add(TypePattern.ELLIPSIS);
		} else {
			patterns.add(parseTypePattern(false, parameterAnnotationsPossible));
		}
	} while (maybeEat(","));
	eat(")");
	return new TypePatternList(patterns);
}

解析参数类型时,以 "," 作为类型分割,每个类型单独解析。(String...,int) 被解析成了两个 TypePattern,"String..." 和 "int",最后封装成 TypePatternList。

public TypePattern parseTypePattern(boolean insideTypeParameters, boolean parameterAnnotationsPossible) {
	TypePattern p = parseAtomicTypePattern(insideTypeParameters, parameterAnnotationsPossible);
	if (maybeEat("&&")) {
		p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters, parameterAnnotationsPossible));
	}

	if (maybeEat("||")) {
		p = new OrTypePattern(p, parseTypePattern(insideTypeParameters, parameterAnnotationsPossible));
	}
	return p;
}

可以看到,转换成了类型解析,执行 parseAtomicTypePattern --> parseSingleTypePattern

// insideTypeParameters false
public TypePattern parseSingleTypePattern(boolean insideTypeParameters) {
	if (insideTypeParameters && maybeEat("?")) {
		return parseGenericsWildcardTypePattern();
	}
	if (allowHasTypePatterns) {
		if (maybeEatIdentifier("hasmethod")) {
			return parseHasMethodTypePattern();
		}
		if (maybeEatIdentifier("hasfield")) {
			return parseHasFieldTypePattern();
		}
	}

	if (maybeEatIdentifier("is")) {
		int pos = tokenSource.getIndex() - 1;
		TypePattern typeIsPattern = parseIsTypePattern();
		if (typeIsPattern != null) {
			return typeIsPattern;
		}
		// rewind as if we never tried to parse it as a typeIs
		tokenSource.setIndex(pos);
	}

    // 按 "." 解析成 NamePattern 集合
	List<NamePattern> names = parseDottedNamePattern();

	int dim = 0;
	while (maybeEat("[")) {
		eat("]");
		dim++;
	}

	TypePatternList typeParameters = maybeParseTypeParameterList();
	int endPos = tokenSource.peek(-1).getEnd();

	boolean includeSubtypes = maybeEat("+");

	// TODO do we need to associate the + with either the type or the array?
	while (maybeEat("[")) {
		eat("]");
		dim++;
	}

	boolean isVarArgs = maybeEat("...");

	// ??? what about the source location of any's????
	if (names.size() == 1 && names.get(0).isAny() && dim == 0 && !isVarArgs && typeParameters == null) {
		return TypePattern.ANY;
	}

	// Notice we increase the dimensions if varargs is set. this is to allow type matching to
	// succeed later: The actual signature at runtime of a method declared varargs is an array type of
	// the original declared type (so Integer... becomes Integer[] in the bytecode). So, here for the
	// pattern 'Integer...' we create a WildTypePattern 'Integer[]' with varargs set. If this matches
	// during shadow matching, we confirm that the varargs flags match up before calling it a successful
	// match.
	return new WildTypePattern(names, includeSubtypes, dim + (isVarArgs ? 1 : 0), endPos, isVarArgs, typeParameters);
}

public List<NamePattern> parseDottedNamePattern() {
	List<NamePattern> names = new ArrayList<>();
	StringBuffer buf = new StringBuffer();
	IToken previous = null;
	boolean justProcessedEllipsis = false; // Remember if we just dealt with an ellipsis (PR61536)
	boolean justProcessedDot = false;
	boolean onADot = false;

	while (true) {
		IToken tok = null;
		int startPos = tokenSource.peek().getStart();
		String afterDot = null;
		while (true) {
			if (previous != null && previous.getString().equals(".")) {
				justProcessedDot = true;
			}
			tok = tokenSource.peek();
			onADot = (tok.getString().equals("."));
			if (previous != null) {
				if (!isAdjacent(previous, tok)) {
					break;
				}
			}
			// "..." 也是标识符,但 "<" 不是
			if (tok.getString() == "*" || (tok.isIdentifier() && tok.getString() != "...")) {
				buf.append(tok.getString());
			} else if (tok.getString() == "...") {
				break;
            // literalKind 为 null,直接 break 退出内循环
			} else if (tok.getLiteralKind() != null) {
				// System.err.println("literal kind: " + tok.getString());
				String s = tok.getString();
				int dot = s.indexOf('.');
				if (dot != -1) {
					buf.append(s.substring(0, dot));
					afterDot = s.substring(dot + 1);
					previous = tokenSource.next();
					break;
				}
				buf.append(s); // ??? so-so
			} else {
				break;
			}
			previous = tokenSource.next();
			// XXX need to handle floats and other fun stuff
		}
		int endPos = tokenSource.peek(-1).getEnd();
		if (buf.length() == 0 && names.isEmpty()) {
			throw new ParserException("name pattern", tok);
		}

		if (buf.length() == 0 && justProcessedEllipsis) {
			throw new ParserException("name pattern cannot finish with ..", tok);
		}
		if (buf.length() == 0 && justProcessedDot && !onADot) {
			throw new ParserException("name pattern cannot finish with .", tok);
		}

		if (buf.length() == 0) {
			names.add(NamePattern.ELLIPSIS);
			justProcessedEllipsis = true;
		} else {
			checkLegalName(buf.toString(), previous);
			NamePattern ret = new NamePattern(buf.toString());
			ret.setLocation(sourceContext, startPos, endPos);
			names.add(ret);
			justProcessedEllipsis = false;
		}

		if (afterDot == null) {
			buf.setLength(0);
			// no elipsis or dotted name part
			if (!maybeEat(".")) {
				break;
				// go on
			} else {
				previous = tokenSource.peek(-1);
			}
		} else {
			buf.setLength(0);
			buf.append(afterDot);
			afterDot = null;
		}
	}
	// System.err.println("parsed: " + names);
	return names;
}

执行 parseDottedNamePattern,按 "." 解析成 NamePattern 集合,也就是将包名和类名按 "." 拆分成单独的部分。对于示例参数类型 "String...",由于未指定包名,解析后 NamePattern 集合 names 中只有一个元素,即 "String"。

接着,由于存在 "...",isVarArgs 为 true。

注意,在配置的切入点表达式中,".." 和 "..." 的含义是不同的。

".."按省略号对待,解析后 ellipsisCount 数量会增加,用在方法参数中,表示任意个参数且参数类型不限
"..."标识符,可变参数,实际解析时按指定类型的数组类型对待

处理完以上的解析点之后,将类型封装为 WildTypePattern。 

WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs, TypePatternList typeParams) {
	super(includeSubtypes, isVarArgs, typeParams);
	this.namePatterns = namePatterns;
	this.dim = dim;
	ellipsisCount = 0;
	for (NamePattern namePattern : namePatterns) {
		if (namePattern == NamePattern.ELLIPSIS) {
			ellipsisCount++;
		}
	}
	setLocation(namePatterns[0].getSourceContext(), namePatterns[0].getStart(), namePatterns[namePatterns.length - 1].getEnd());
}
protected TypePattern(boolean includeSubtypes, boolean isVarArgs, TypePatternList typeParams) {
	this.includeSubtypes = includeSubtypes;
	this.isVarArgs = isVarArgs;
	this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams);
}

可以看到封装的 WildTypePattern 将 namePatterns 和 typeParameters 分开了,namePatterns 只包含类型定义。 

类型绑定

解析完之后,得到 Pointcut,接着构建一个解析范围,也就是 @Aspect 切面类,切点表达式定义在切面类中。

// Pointcut
public final Pointcut resolve(IScope scope) {
	assertState(SYMBOLIC);
    // scope.getFormalCount() 获取的就是用户在切面方法上显式指定的参数数量
	Bindings bindingTable = new Bindings(scope.getFormalCount());
	IScope bindingResolutionScope = scope;
	if (typeVariablesInScope.length > 0) {
		bindingResolutionScope = new ScopeWithTypeVariables(typeVariablesInScope, scope);
	}
	this.resolveBindings(bindingResolutionScope, bindingTable);
	bindingTable.checkAllBound(bindingResolutionScope);
	this.state = RESOLVED;
	return this;
}

执行 resolveBindings 就是进行类型的解析绑定。

在 KindedPointcut#resolveBindings 中,执行 signature.resolveBindings(scope, bindings)。

// SignaturePattern
@Override
public SignaturePattern resolveBindings(IScope scope, Bindings bindings) {
	if (returnType != null) {
		returnType = returnType.resolveBindings(scope, bindings, false, false);
		checkForIncorrectTargetKind(returnType, scope, false);
	}
	if (declaringType != null) {
		declaringType = declaringType.resolveBindings(scope, bindings, false, false);
		checkForIncorrectTargetKind(declaringType, scope, false);
		isExactDeclaringTypePattern = (declaringType instanceof ExactTypePattern);
	}
	if (parameterTypes != null) {
		parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
		checkForIncorrectTargetKind(parameterTypes, scope, false, true);
	}
	if (throwsPattern != null) {
		throwsPattern = throwsPattern.resolveBindings(scope, bindings);
		if (throwsPattern.getForbidden().getTypePatterns().length > 0
				|| throwsPattern.getRequired().getTypePatterns().length > 0) {
			checkForIncorrectTargetKind(throwsPattern, scope, false);
		}
	}
	if (annotationPattern != null) {
		annotationPattern = annotationPattern.resolveBindings(scope, bindings, false);
		checkForIncorrectTargetKind(annotationPattern, scope, true);
	}
	hashcode = -1;
	return this;
}

可以看到,分别针对返回值类型,方法定义类型、参数类型、异常类型、注解类型进行了绑定。我们主要来看下参数绑定。

上面的 parameterTypes,其实就是方法参数解析之后封装的 TypePatternList。

// TypePatternList
public TypePatternList resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
	for (int i = 0; i < typePatterns.length; i++) {
		TypePattern p = typePatterns[i];
		if (p != null) {
			typePatterns[i] = typePatterns[i].resolveBindings(scope, bindings, allowBinding, requireExactType);
		}
	}
	return this;
}

遍历每一个类型对应的 TypePattern,逐个进行绑定。除 "*" 外,其余的类型在切入点表达式解析时都会被解析为 WildTypePattern,所以此处会执行 WildTypePattern#resolveBindings 进行类型的绑定。

// WildTypePattern
@Override
public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
	// NamePattern 是 "*"
	if (isNamePatternStar()) {
		TypePattern anyPattern = maybeResolveToAnyPattern(scope, bindings, allowBinding, requireExactType);
		if (anyPattern != null) {
			if (requireExactType) {
				scope.getWorld().getMessageHandler().handleMessage(
						MessageUtil.error(WeaverMessages.format(WeaverMessages.WILDCARD_NOT_ALLOWED), getSourceLocation()));
				return NO;
			} else {
				return anyPattern;
			}
		}
	}
    // 返回 null
	TypePattern bindingTypePattern = maybeResolveToBindingTypePattern(scope, bindings, allowBinding, requireExactType);
	if (bindingTypePattern != null) {
		return bindingTypePattern;
	}

	annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding);

	// resolve any type parameters
	// 类型泛型参数
    // 先对泛型参数类型进行绑定
	if (typeParameters != null && typeParameters.size() > 0) {
		typeParameters.resolveBindings(scope, bindings, allowBinding, requireExactType);
		isGeneric = false;
	}

	// resolve any bounds
	if (upperBound != null) {
		upperBound = upperBound.resolveBindings(scope, bindings, allowBinding, requireExactType);
	}
	if (lowerBound != null) {
		lowerBound = lowerBound.resolveBindings(scope, bindings, allowBinding, requireExactType);
		// amc - additional interface bounds only needed if we support type vars again.
	}
    
    // 获取全限定性类名
	String fullyQualifiedName = maybeGetCleanName();  // String
    // 全限定性类名不为 null,才执行绑定
	if (fullyQualifiedName != null) {
		return resolveBindingsFromFullyQualifiedTypeName(fullyQualifiedName, scope, bindings, allowBinding, requireExactType);
	} else {
		if (requireExactType) {
			scope.getWorld().getMessageHandler().handleMessage(
					MessageUtil.error(WeaverMessages.format(WeaverMessages.WILDCARD_NOT_ALLOWED), getSourceLocation()));
			return NO;
		}
		importedPrefixes = scope.getImportedPrefixes();
		knownMatches = preMatch(scope.getImportedNames());
		return this; // pattern contains wildcards so can't be resolved to an ExactTypePattern...
		// XXX need to implement behavior for Lint.invalidWildcardTypeName
	}
}
private TypePattern maybeResolveToBindingTypePattern(IScope scope, Bindings bindings, boolean allowBinding,
		boolean requireExactType) {
	// namePatterns 长度为 1,获取 simpleName 
	// 例如 int 类型
	String simpleName = maybeGetSimpleName();
	if (simpleName != null) {
		// scope 为 BindingScope,继承 SimpleScope
		// 返回 null
		FormalBinding formalBinding = scope.lookupFormal(simpleName); // null
		if (formalBinding != null) {
			if (bindings == null) {
				scope.message(IMessage.ERROR, this, "negation doesn't allow binding");
				return this;
			}
			if (!allowBinding) {
				scope.message(IMessage.ERROR, this, "name binding only allowed in target, this, and args pcds");
				return this;
			}

			BindingTypePattern binding = new BindingTypePattern(formalBinding, isVarArgs);
			binding.copyLocationFrom(this);
			bindings.register(binding, scope);

			return binding;
		}
	}
	return null; // not possible to resolve to a binding type pattern
}

由外部传入的 parameterNames 和 parameterTypes 封装的 org.aspectj.weaver.tools.PointcutParameter 数组,在构建 IScope 时,解析为 FormalBinding 数组,封装在 IScope 的实现类 BindingScope 中。执行 scope.lookupFormal(simpleName) 时,遍历 FormalBinding 数组,判断 FormalBinding 数组元素持有的 name 是否和 simpleName 相等,相等则将当前 FormalBinding 返回。外部未传入 parameterNames 和 parameterTypes 时,执行 maybeResolveToBindingTypePattern 返回 null。我们在前面的文章                                         《AspectJ 中通知方法参数绑定》中介绍过,显式指定的参数在之后的 checkAllBound 方法执行时都会抛出异常,所以使用时不会自定义显式参数,即此处恒返回 null。

有一点注意,当获取全限定性类名 fullyQualifiedName 时,如果配置的表达式中表示类型的部分含有 "*",则表示不确定,获取的 fullyQualifiedName 为 null。只有 fullyQualifiedName 不为 null,才会执行真正的绑定。否则,会将原 WildTypePattern 返回。

// WildTypePattern
private TypePattern resolveBindingsFromFullyQualifiedTypeName(String fullyQualifiedName, IScope scope, Bindings bindings,
		boolean allowBinding, boolean requireExactType) {
	String originalName = fullyQualifiedName;
	ResolvedType resolvedTypeInTheWorld = null;
	UnresolvedType type;

	// System.out.println("resolve: " + cleanName);
	// ??? this loop has too many inefficiencies to count
	resolvedTypeInTheWorld = lookupTypeInWorldIncludingPrefixes(scope.getWorld(), fullyQualifiedName, scope
			.getImportedPrefixes());

	if (resolvedTypeInTheWorld.isGenericWildcard()) {
		type = resolvedTypeInTheWorld;
	} else {
		type = lookupTypeInScope(scope, fullyQualifiedName, this);
	}
	// 在 scope 中未找到
	if ((type instanceof ResolvedType) && ((ResolvedType) type).isMissing()) {
		return resolveBindingsForMissingType(resolvedTypeInTheWorld, originalName, scope, bindings, allowBinding,
				requireExactType);
	} else {
		// scope 中找到,解析绑定的确切类型
		return resolveBindingsForExactType(scope, type, fullyQualifiedName, requireExactType);
	}
}
private ResolvedType lookupTypeInWorldIncludingPrefixes(World world, String typeName, String[] prefixes) {
	ResolvedType ret = lookupTypeInWorld(world, typeName); // String
	if (!ret.isMissing()) {
		return ret;
	}
	ResolvedType retWithPrefix = ret;
	int counter = 0;
	// 丢失了,加上前缀接着找,默认的前缀一个 "java.lang.",找到了,退出循环,此时 retWithPrefix 为 ReferenceType
	while (retWithPrefix.isMissing() && (counter < prefixes.length)) {
		retWithPrefix = lookupTypeInWorld(world, prefixes[counter] + typeName);
		counter++;
	}
	// 找到了,将 retWithPrefix 返回
	if (!retWithPrefix.isMissing()) {
		return retWithPrefix;
	}
	return ret;
}
private ResolvedType lookupTypeInWorld(World world, String typeName) {
	UnresolvedType ut = UnresolvedType.forName(typeName);   // signature = "LString;"    -->  new UnresolvedType(signature);
	ResolvedType ret = world.resolve(ut, true);  // 调用 World#resolve --> World#resolveToReferenceType
	// ret 为 MissingResolvedTypeWithKnownSignature 时,isMissing() 返回 true
	while (ret.isMissing()) {
		int lastDot = typeName.lastIndexOf('.');
		// "String" 跳出循环
		if (lastDot == -1) {
			break;
		}
		// 内部类
		typeName = typeName.substring(0, lastDot) + '$' + typeName.substring(lastDot + 1);
		ret = world.resolve(UnresolvedType.forName(typeName), true);
	}
	return ret;
}

在 lookTypeInWorldIncludingPrefixes 中,先对确定的全限定性类名,即 typeName,执行 lookupTypeInWorld,其实就是利用传入的 World,对 typeName 进行解决。

scope.getImportedPrefixes(),在 SimpleScope 中,默认 importedPrefixes 为 "java.lang."。

当 typeName 为 "String" 时,执行 WildTypePattern#lookupTypeInWorld,在方法中,利用 World 将 ut 处理为 ResolvedType。

public ResolvedType resolve(UnresolvedType ty, boolean allowMissing) {

	// special resolution processing for already resolved types.
	if (ty instanceof ResolvedType) {
		ResolvedType rty = (ResolvedType) ty;
		rty = resolve(rty);
		// A TypeVariableReferenceType may look like it is resolved (it extends ResolvedType) but the internal
		// type variable may not yet have been resolved
		if (!rty.isTypeVariableReference() || ((TypeVariableReferenceType) rty).isTypeVariableResolved()) {
			return rty;
		}
	}

	// dispatch back to the type variable reference to resolve its
	// constituent parts don't do this for other unresolved types otherwise
	// you'll end up in a
	// loop
	if (ty.isTypeVariableReference()) {
		return ty.resolve(this);
	}

	// if we've already got a resolved type for the signature, just return
	// it
	// after updating the world
	String signature = ty.getSignature();
	ResolvedType ret = typeMap.get(signature);
	if (ret != null) {
		ret.world = this; // Set the world for the RTX
		return ret;
	} else if (signature.equals("?") || signature.equals("*")) {
		// might be a problem here, not sure '?' should make it to here as a
		// signature, the
		// proper signature for wildcard '?' is '*'
		// fault in generic wildcard, can't be done earlier because of init
		// issues
		// TODO ought to be shared single instance representing this
		ResolvedType something = getWildcard();
		typeMap.put("?", something);
		return something;
	}

	// no existing resolved type, create one
	synchronized (buildingTypeLock) {
		if (ty.isArray()) {
			ResolvedType componentType = resolve(ty.getComponentType(), allowMissing);
			ret = new ArrayReferenceType(signature, "[" + componentType.getErasureSignature(), this, componentType);
		} else {
			ret = resolveToReferenceType(ty, allowMissing);
			if (!allowMissing && ret.isMissing()) {
				ret = handleRequiredMissingTypeDuringResolution(ty);
			}
			if (completeBinaryTypes) {
				completeBinaryType(ret);
			}
		}
	}

	// Pulling in the type may have already put the right entry in the map
	ResolvedType result = typeMap.get(signature);
	if (result == null && !ret.isMissing()) {
		ret = ensureRawTypeIfNecessary(ret);
		typeMap.put(signature, ret);
		return ret;
	}
	if (result == null) {
		return ret;
	} else {
		return result;
	}
}
// World
// 解析为 ReferenceType
private final ResolvedType resolveToReferenceType(UnresolvedType ty, boolean allowMissing) {
	if (ty.isParameterizedType()) {
		// ======= parameterized types ================
		ResolvedType rt = resolveGenericTypeFor(ty, allowMissing);
		if (rt.isMissing()) {
			return rt;
		}
		ReferenceType genericType = (ReferenceType) rt;
		ReferenceType parameterizedType = TypeFactory.createParameterizedType(genericType, ty.typeParameters, this);
		return parameterizedType;

	} else if (ty.isGenericType()) {
		// ======= generic types ======================
		ResolvedType rt = resolveGenericTypeFor(ty, false);
		if (rt.isMissing()) {
			return rt;
		}
		ReferenceType genericType = (ReferenceType) rt;
		if (rt.isMissing()) {
			return rt;
		}
		return genericType;

	} else if (ty.isGenericWildcard()) {
		// ======= generic wildcard types =============
		return resolveGenericWildcardFor((WildcardedUnresolvedType) ty);
	} else {
		// ======= simple and raw types ===============
        // 获取泛型擦除后的签名字符串
		String erasedSignature = ty.getErasureSignature();
		ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this);
		if (ty.needsModifiableDelegate()) {
			simpleOrRawType.setNeedsModifiableDelegate(true);
		}
		// 针对 "String" 创建 delegate 时,利用 ClassLoader 加载 "String",无法加载,返回 null
		ReferenceTypeDelegate delegate = resolveDelegate(simpleOrRawType);

		if (delegate == null) {
			// MissingResolvedTypeWithKnownSignature 继承 ResolvedType,ResolvedType 继承 UnresolvedType
			return new MissingResolvedTypeWithKnownSignature(ty.getSignature(), erasedSignature, this);
		}

		if (delegate.isGeneric() && behaveInJava5Way) {
			// ======== raw type ===========
			simpleOrRawType.typeKind = TypeKind.RAW;
			if (simpleOrRawType.hasNewInterfaces()) { // debug 375777
				throw new IllegalStateException(
						"Simple type promoted forced to raw, but it had new interfaces/superclass.  Type is "
								+ simpleOrRawType.getName());
			}
			ReferenceType genericType = makeGenericTypeFrom(delegate, simpleOrRawType);
			simpleOrRawType.setDelegate(delegate);
			genericType.setDelegate(delegate);
			simpleOrRawType.setGenericType(genericType);
			return simpleOrRawType;
		} else {
			// ======== simple type =========
			simpleOrRawType.setDelegate(delegate);
			return simpleOrRawType;
		}
	}
}

将 UnresolvedType 解析为 ReferenceType 之后,会为其创建一个 delegate。

public static ReflectionBasedReferenceTypeDelegate createDelegate(ReferenceType forReferenceType, World inWorld,
		ClassLoader usingClassLoader) {
	try {
		Class c = Class.forName(forReferenceType.getName(), false, usingClassLoader);
		ReflectionBasedReferenceTypeDelegate rbrtd = create15Delegate(forReferenceType, c, usingClassLoader, inWorld);
		if (rbrtd != null) {
			return rbrtd; // can be null if we didn't find the class the delegate logic loads
		}
		return new ReflectionBasedReferenceTypeDelegate(c, usingClassLoader, inWorld, forReferenceType);
	} catch (ClassNotFoundException cnfEx) {
		return null;
	}
}

private static ReflectionBasedReferenceTypeDelegate create15Delegate(ReferenceType forReferenceType, Class forClass,
		ClassLoader usingClassLoader, World inWorld) {
	try {
		Class delegateClass = Class.forName("org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate");
		ReflectionBasedReferenceTypeDelegate ret = (ReflectionBasedReferenceTypeDelegate) delegateClass.getDeclaredConstructor().newInstance();
		ret.initialize(forReferenceType, forClass, usingClassLoader, inWorld);
		return ret;
	} catch (ClassNotFoundException cnfEx) {
		throw new IllegalStateException(
				"Attempted to create Java 1.5 reflection based delegate but org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate was not found on classpath");
	} catch (InstantiationException insEx) {
		throw new IllegalStateException("Attempted to create Java 1.5 reflection based delegate but InstantiationException: "
				+ insEx + " occured");
	} catch (IllegalAccessException illAccEx) {
		throw new IllegalStateException("Attempted to create Java 1.5 reflection based delegate but IllegalAccessException: "
				+ illAccEx + " occured");
	} catch (NoSuchMethodException nsMethEx) {
		throw new IllegalStateException("Attempted to create Java 1.5 reflection based delegate but NoSuchMethodException: "
				+ nsMethEx + " occured");
	} catch (InvocationTargetException invTargEx) {
		throw new IllegalStateException("Attempted to create Java 1.5 reflection based delegate but InvocationTargetException: "
				+ invTargEx + " occured");
	}
}

利用 classLoader 去加载 "String",此时捕获异常,返回 null,由于 delegate 为 null,会创建一个 MissingResolvedTypeWithKnownSignature 返回。MissingResolvedTypeWithKnownSignature 继承 ResolvedType。

MissingResolvedTypeWithKnownSignature#isMissing 返回 true,此时在 lookupTypeInWorldIncludingPrefixes 方法中,遍历 prefixes 数组,给无法加载的类型,加上前缀接着执行 lookupTypeInWorld 去查找,"String" 变成 "java.lang.String",这一次可以加载。利用反射创建一个 Java15ReflectionBasedReferenceTypeDelegate,并完成初始化。之后为 simpleOrRawType 设置 delegate 之后返回,接着退出循环,此时 retWithPrefix 为 ReferenceType。

接着,由于 resolvedTypeInTheWorld.isGenericWildcard() 返回 false,执行 lookupTypeInScope,在 scope 中再查找一遍。

// WildTypePattern
// 此处参数 loacation,即 WildTypePattern
private UnresolvedType lookupTypeInScope(IScope scope, String typeName, IHasPosition location) {
	UnresolvedType type = null;
	while (ResolvedType.isMissing(type = scope.lookupType(typeName, location))) {  // typeName "String"
		int lastDot = typeName.lastIndexOf('.');
		if (lastDot == -1) {
			break;
		}
		typeName = typeName.substring(0, lastDot) + '$' + typeName.substring(lastDot + 1);
	}
	return type;
}
// BindingsScope
public UnresolvedType lookupType(String name, IHasPosition location) {
    // 扩展 importedPrefixes
	// bug 126560
	if (enclosingType != null && !importsUpdated) {
		// add the package we're in to the list of imported
		// prefixes so that we can find types in the same package
		String pkgName = enclosingType.getPackageName();  // 切面类包名
		if (pkgName != null && !pkgName.equals("")) {
			String[] existingImports = getImportedPrefixes();  // {"java.lang."}
			String pkgNameWithDot = pkgName.concat(".");  // pkgName + "."
			boolean found = false;
			for (String existingImport : existingImports) {
				if (existingImport.equals(pkgNameWithDot)) {
					found = true;
					break;
				}
			}
			// 变更 SimpleScope 中 importedPrefixes
			if (!found) {
				String[] newImports = new String[existingImports.length + 1];
				System.arraycopy(existingImports, 0, newImports, 0, existingImports.length);
				newImports[existingImports.length] = pkgNameWithDot;
				setImportedPrefixes(newImports);
			}
		}
		importsUpdated = true;
	}
	return super.lookupType(name, location);
}
// BindingScope 父类 SimpleScope
public UnresolvedType lookupType(String name, IHasPosition location) {
	for (String importedName : importedNames) {  // {}
		// make sure we're matching against the type name rather than part of it
		// if (importedName.endsWith("." + name)) {
		if (importedName.endsWith(name)) {
			return world.resolve(importedName);
		}
	}

	// Check for a primitive
	if (name.length() < 8 && Character.isLowerCase(name.charAt(0))) {
		// could be a primitive
		int len = name.length();
		if (len == 3) {
			if (name.equals("int")) {
				return UnresolvedType.INT;
			}
		} else if (len == 4) {
			if (name.equals("void")) {
				return UnresolvedType.VOID;
			} else if (name.equals("byte")) {
				return UnresolvedType.BYTE;
			} else if (name.equals("char")) {
				return UnresolvedType.CHAR;
			} else if (name.equals("long")) {
				return UnresolvedType.LONG;
			}
		} else if (len == 5) {
			if (name.equals("float")) {
				return UnresolvedType.FLOAT;
			} else if (name.equals("short")) {
				return UnresolvedType.SHORT;
			}
		} else if (len == 6) {
			if (name.equals("double")) {
				return UnresolvedType.DOUBLE;
			}
		} else if (len == 7) {
			if (name.equals("boolean")) {
				return UnresolvedType.BOOLEAN;
			}
		}
	}

	// Is it fully qualified?
	// 全类型指定,直接解析
	if (name.indexOf('.') != -1) {
		return world.resolve(UnresolvedType.forName(name), true);
	}

	// 遍历前缀,加前缀解析
	for (String importedPrefix : importedPrefixes) {
		ResolvedType tryType = world.resolve(UnresolvedType.forName(importedPrefix + name), true);
		if (!tryType.isMissing()) {
			return tryType;
		}
	}

	return world.resolve(UnresolvedType.forName(name), true);
}

可以看到,先对默认的 importedPrefixes 进行了扩充,将切面类所在包名也扩充了进去。接着执行 SimpleScope#lookupType,对基本类型和全限定类型,单独处理,针对 "String",会加上前缀进行解析,解析为 ReferenceType,直接返回。此处执行 world.resolve 时,如果之前已经对相应类型进行过解析,则会直接从 World 中的缓存字段 typeMap 中获取到对应的 ResolvedType。

由于已经判断为确定的类型,接下来执行绑定的最后一步,调用 WildTypePattern#resolveBindingsForExactType,封装 ExactTypePattern

// WildTypePattern
private TypePattern resolveBindingsForExactType(IScope scope, UnresolvedType aType, String fullyQualifiedName,
		boolean requireExactType) {
	TypePattern ret = null;
	if (aType.isTypeVariableReference()) {
		// we have to set the bounds on it based on the bounds of this pattern
		ret = resolveBindingsForTypeVariable(scope, (UnresolvedTypeVariableReferenceType) aType);
	} else if (typeParameters.size() > 0) {
        // 存在泛型参数时处理方式
		ret = resolveParameterizedType(scope, aType, requireExactType);
	} else if (upperBound != null || lowerBound != null) {
		// this must be a generic wildcard with bounds
        // 泛型类型存在边界
		ret = resolveGenericWildcard(scope, aType);
	} else {
		// String... 可变参数,dim 不为 0
		if (dim != 0) {
			aType = UnresolvedType.makeArray(aType, dim);  // 数组类型 java.lang.String[]
		}
		ret = new ExactTypePattern(aType, includeSubtypes, isVarArgs);
	}
	ret.setAnnotationTypePattern(annotationPattern);
	ret.copyLocationFrom(this);
	return ret;
}

此处根据不同的条件,执行不同的封装策略。如果存在泛型参数,执行 WildTypePattern#resolveParameterizedType,将 WildTypePattern 封装为 ExactTypePattern。

默认情况下,如果 dim 不为 0,即存在数组类型或可变参数,将其统一处理为数组类型对应的字节码签名

public static UnresolvedType makeArray(UnresolvedType base, int dims) {
	StringBuffer sig = new StringBuffer();
	for (int i = 0; i < dims; i++) {
		sig.append("[");
	}
	sig.append(base.getSignature());  // "[Ljava/lang/String;"
	return UnresolvedType.forSignature(sig.toString());
}

 例如,base 为 "java.lang.String",处理后,signature 变为 "[Ljava/lang/String",接着利用 TypeFactory#createTypeFromSignature 为 signature 创建 UnresolvedType。

// TypeFactory#createTypeFromSignature
...
} else if (firstChar == '[') {
	int dims = 0;
	while (signature.charAt(dims) == '[') {
		dims++;
	}
    // 数组元素类型
	UnresolvedType componentType = createTypeFromSignature(signature.substring(dims));
	return new UnresolvedType(signature, signature.substring(0, dims) + componentType.getErasureSignature());
}
...

针对签名字符串 "Ljava/lang/String;" 和 "[Ljava/lang/String;" 分别创建 UnresolvedType,之后将数组签名字符串创建的 UnresolvedType 返回,视为 aType。

之后,封装一个 ExactTypePattern。就这样,将一个 "String..." 解析为 java.lang.String[]。

顺便说下,由于在 scope.lookupType 中对 importedPrefixes 进行了扩充,也就是和切面类在同一个包下的类,配置为切入点表达式类型时,也可以简写为类名的形式,不用指定包名。

示例二

execution(* *..UserServiceImpl.doSome(java.util.List<String>,int))

参数解析

经过前面的介绍,我们知道,(java.util.List<String>,int) 会被解析成两个 TypePattern,之后封装成一个 TypePatternList。解析第一个参数类型时,由于存在泛型参数,会调用 PatternParser#maybeParseTypeParameterList。

// 泛型参数解析 "<,>"
public TypePatternList maybeParseTypeParameterList() {
	if (!maybeEat("<")) {
		return null;
	}
	List<TypePattern> typePats = new ArrayList<>();
	do {
		TypePattern tp = parseTypePattern(true, false);
		typePats.add(tp);
	} while (maybeEat(","));
	eat(">");
	TypePattern[] tps = new TypePattern[typePats.size()];
	typePats.toArray(tps);
	return new TypePatternList(tps);
}

可以看到,又转化为对单个类型的解析。之后将所有的泛型参数类型封装成一个 TypePatternList。

此处将 "java.util.List<String>" 封装为 WildTypePattern,持有字段 typeParameters 为 "String" 封装的 WildTypePattern 所组成的 TypePatternList。

类型绑定

直接来看参数绑定,在 WildTypePattern#resolveBindings 中,针对 "java.util.List<String>" 封装的 WildTypePattern,由于 typeParameters 不为 null。执行 typeParameters.resolveBindings(...),即执行 TypeParameterList#resolveBindings。遍历每一个泛型类型,执行 WildTypePattern#resolveBindings。也就是说,只要是类型,最终都会转换到 WildTypePattern#resolveBindings 来执行。

将 "String" 封装的 WildTypePattern,在 WildTypePattern#resolveBindingsFromFullyQualifiedTypeName 中添加默认前缀,处理为 "java.lang.String",之后封装为 ExactTypePattern。

接着来看 "java.util.List" 的绑定,在 WildTypePattern#resolveBindings 中,得到fullyQualifiedName 为 "java.util.List",接着执行 WildTypePattern#resolveBindingsFromFullyQualifiedTypeName --> lookupTypeInWorldIncludingPrefixes  --> lookupTypeInWorld,先将 "java.util.List" 封装成 typeKind 为 TypeKind.SIMPLE 的 UnresolvedType,之后执行 World#resolve。在 typeMap 中未查找到,执行 World#resolveToReferenceType。封装 simpleOrRawType,之后为其创建 delegate。利用 classLoader 加载 "java.util.List" 得到 aClass,在 Java15ReflectionBasedReferenceTypeDelegate#initialize 方法中将 aClass 传递给 Java15ReflectionBasedReferenceTypeDelegate 父类 ReflectionBasedReferenceTypeDelegate 中 myClass 字段。

创建完 delegate,在 World#resolveToReference 中,调用 delegate.isGeneric()。

@Override
public boolean isGeneric() {
	// return false; // for now
	return getBaseClass().getTypeParameters().length > 0;
}
protected Class getBaseClass() {
	return this.myClass;
}

java.util.List 定义时就存在泛型参数,所以此时返回 true。将 simpleOrRawType 中 typeKind 修改为 TypeKind.RAW,接着执行 World#makeGenericTypeFrom。

// World
private ReferenceType makeGenericTypeFrom(ReferenceTypeDelegate delegate, ReferenceType rawType) {
	String genericSig = delegate.getDeclaredGenericSignature();
	if (genericSig != null) {
		return new ReferenceType(UnresolvedType.forGenericTypeSignature(rawType.getSignature(),
				delegate.getDeclaredGenericSignature()), this);
	} else {
        // 执行 else
		return new ReferenceType(UnresolvedType.forGenericTypeVariables(rawType.getSignature(), delegate.getTypeVariables()),
				this);
	}
}

// Java15ReflectionBasedReferenceTypeDelegate
@Override
public TypeVariable[] getTypeVariables() {
    // null
	TypeVariable[] workInProgressSetOfVariables = getResolvedTypeX().getWorld().getTypeVariablesCurrentlyBeingProcessed(
			getBaseClass());
	if (workInProgressSetOfVariables != null) {
		return workInProgressSetOfVariables;
	}
	if (this.typeVariables == null) {
		java.lang.reflect.TypeVariable[] tVars = this.getBaseClass().getTypeParameters();
        // org.aspectj.weaver.TypeVariable
		TypeVariable[] rTypeVariables = new TypeVariable[tVars.length];
		// basic initialization
		for (int i = 0; i < tVars.length; i++) {
			rTypeVariables[i] = new TypeVariable(tVars[i].getName());
		}
		// stash it
		this.getResolvedTypeX().getWorld().recordTypeVariablesCurrentlyBeingProcessed(getBaseClass(), rTypeVariables);
		// now fill in the details...
		for (int i = 0; i < tVars.length; i++) {
            // 处理 java.lang.reflect.TypeVariable,将其处理成 TypeVariableReferenceType
			TypeVariableReferenceType tvrt = ((TypeVariableReferenceType) typeConverter.fromType(tVars[i]));
			TypeVariable tv = tvrt.getTypeVariable();
			rTypeVariables[i].setSuperclass(tv.getSuperclass());
			rTypeVariables[i].setAdditionalInterfaceBounds(tv.getSuperInterfaces());
			rTypeVariables[i].setDeclaringElement(tv.getDeclaringElement());
			rTypeVariables[i].setDeclaringElementKind(tv.getDeclaringElementKind());
			rTypeVariables[i].setRank(tv.getRank());
		}
		this.typeVariables = rTypeVariables;
		this.getResolvedTypeX().getWorld().forgetTypeVariablesCurrentlyBeingProcessed(getBaseClass());
	}
	return this.typeVariables;
}

// JavaLangTypeToResolvedTypeConverter
public ResolvedType fromType(Type type) {
	if (type instanceof Class) {
		Class clazz = (Class) type;
		String name = clazz.getName();
		/**
		 * getName() can return:
		 *
		 * 1. If this class object represents a reference type that is not an
		 * array type then the binary name of the class is returned
		 * 2. If this class object represents a primitive type or void, then
		 * the name returned is a String equal to the Java language keyword
		 * corresponding to the primitive type or void.
		 * 3. If this class object represents a class of arrays, then the internal
		 * form of the name consists of the name of the element type preceded by
		 * one or more '[' characters representing the depth of the array nesting.
		 */
		if (clazz.isArray()) {
			UnresolvedType ut = UnresolvedType.forSignature(name.replace('.', '/'));
			return getWorld().resolve(ut);
		} else {
			return getWorld().resolve(name);
		}
	} else if (type instanceof ParameterizedType) {
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=509327
		// TODO should deal with the ownerType if it set, indicating this is possibly an inner type of a parameterized type
		Type ownerType = ((ParameterizedType) type).getOwnerType();
		ParameterizedType parameterizedType = (ParameterizedType) type;
		ResolvedType baseType = fromType(parameterizedType.getRawType());
		Type[] typeArguments = parameterizedType.getActualTypeArguments();
		if (baseType.isSimpleType() && typeArguments.length == 0 && ownerType != null) {
			// 'type' is an inner type of some outer parameterized type
			// For now just return the base type - in future create the parameterized form of the outer
			// and use it with the inner. We return the base type to be compatible with what the
			// code does that accesses the info from the bytecode (unlike this code which accesses it
			// reflectively).
			return baseType;
		}
		ResolvedType[] resolvedTypeArguments = fromTypes(typeArguments);
		return TypeFactory.createParameterizedType(baseType, resolvedTypeArguments, getWorld());
	} else if (type instanceof java.lang.reflect.TypeVariable) {
		TypeVariableReferenceType inprogressVar = typeVariablesInProgress.get(type);
		if (inprogressVar != null) {
			return inprogressVar;
		}
		java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) type;
		// org.aspectj.weaver.TypeVariable
		TypeVariable rt_tv = new TypeVariable(tv.getName());
		// 将 rt_tv 封装为 TypeVariableReferenceType
		TypeVariableReferenceType tvrt = new TypeVariableReferenceType(rt_tv, getWorld());
		typeVariablesInProgress.put(type, tvrt); // record what we are working on, for recursion case
		// 处理边界
		Type[] bounds = tv.getBounds();
		ResolvedType[] resBounds = fromTypes(bounds);
		ResolvedType upperBound = resBounds[0];
		ResolvedType[] additionalBounds = new ResolvedType[0];
		if (resBounds.length > 1) {
			additionalBounds = new ResolvedType[resBounds.length - 1];
			System.arraycopy(resBounds, 1, additionalBounds, 0, additionalBounds.length);
		}
		rt_tv.setUpperBound(upperBound);
		rt_tv.setAdditionalInterfaceBounds(additionalBounds);
		typeVariablesInProgress.remove(type); // we have finished working on it
		return tvrt;
	} else if (type instanceof WildcardType) {
		WildcardType wildType = (WildcardType) type;
		Type[] lowerBounds = wildType.getLowerBounds();
		Type[] upperBounds = wildType.getUpperBounds();
		ResolvedType bound = null;
		boolean isExtends = lowerBounds.length == 0;
		if (isExtends) {
			bound = fromType(upperBounds[0]);
		} else {
			bound = fromType(lowerBounds[0]);
		}
		return new BoundedReferenceType((ReferenceType) bound, isExtends, getWorld());
	} else if (type instanceof GenericArrayType) {
		GenericArrayType genericArrayType = (GenericArrayType) type;
		Type componentType = genericArrayType.getGenericComponentType();
		return UnresolvedType.makeArray(fromType(componentType), 1).resolve(getWorld());
	}
	return ResolvedType.MISSING;
}

public TypeVariableReferenceType(TypeVariable typeVariable, World world) {
	super(typeVariable.getGenericSignature(), typeVariable.getErasureSignature(), world);
	this.typeVariable = typeVariable;
}
public String getGenericSignature() {
	return "T" + name + ";";
}
public String getErasureSignature() {
	return getFirstBound().getErasureSignature();
}

// org.aspectj.weaver.TypeVariable
// 未指定返回 UnresolvedType.OBJECT
public UnresolvedType getFirstBound() {
	if (firstbound != null) {
		return firstbound;
	}
	if (superclass == null || superclass.getSignature().equals("Ljava/lang/Object;")) {
		if (superInterfaces.length > 0) {
			firstbound = superInterfaces[0];
		} else {
			firstbound = UnresolvedType.OBJECT;
		}
	} else {
		firstbound = superclass;
	}
	return firstbound;
}

public static UnresolvedType forGenericTypeVariables(String sig, TypeVariable[] tVars) {
	UnresolvedType ret = UnresolvedType.forSignature(sig);
	ret.typeKind = TypeKind.GENERIC;
	ret.typeVariables = tVars;
	ret.signatureErasure = sig;
	ret.signature = ret.signatureErasure;
	return ret;
}

public ReferenceType(UnresolvedType genericType, World world) {
	super(genericType.getSignature(), world);
	typeKind = TypeKind.GENERIC;
	this.typeVariables = genericType.typeVariables;
}

由于解析切入点表达式时,将一个类型中的类型和泛型分开解析,所以此处 this.getBaseClass().getTypeParameters() 相当于泛型擦除之后获取定义时的泛型变量,即 java.lang.reflect.TypeVariable。之后将 java.lang.reflect.TypeVariable 转换为 org.aspectj.weaver.TypeVariable。可以看到,对泛型类型变量的处理都是委托给 delegate 来处理的。

接着调用 UnresolvedType#forGenericTypeVariables,封装一个 typeKind 为 TypeKind.GENERIC 的 UnresolvedType,之后又依赖这个 UnresolvedType 封装一个 ReferenceType,作为 genericType,simpleOrRawType 和 genericType 共用一个 delegate,调用 ReferenceType#setGenericType,为 simpleOrRawType 中 genericType 属性赋值。最后将这个 simpleOrRawType 返回并缓存在 typeMap 中。

接着在 WildTypePattern#resolveBindingsFromFullyQualifiedTypeName 中调用 lookupTypeInScope,由于 "Ljava/util/List;" 已经缓存在了 typeMap 中,所以这一次直接从缓存获取。

完成这些准备工作之后,调用 WildTypePattern#resolveBindingsForExactType,此时由于存在 typeParameters,调用 WildTypePattern#resolveParameterizedType。

// WildTypePattern
private TypePattern resolveParameterizedType(IScope scope, UnresolvedType aType, boolean requireExactType) {
	// 保证 aType 已经解析
	ResolvedType rt = aType.resolve(scope.getWorld());
	if (!verifyTypeParameters(rt, scope, requireExactType)) {
		return TypePattern.NO; // messages already isued
	}
	// Only if the type is exact *and* the type parameters are exact should we create an
	// ExactTypePattern for this WildTypePattern
	// 实际泛型参数类型都已确定,且是否不允许子类型
	if (typeParameters.areAllExactWithNoSubtypesAllowed()) {
		TypePattern[] typePats = typeParameters.getTypePatterns();
		UnresolvedType[] typeParameterTypes = new UnresolvedType[typePats.length];
		for (int i = 0; i < typeParameterTypes.length; i++) {
			typeParameterTypes[i] = ((ExactTypePattern) typePats[i]).getExactType();
		}
		// rt could be a parameterized type 156058
		if (rt.isParameterizedType()) {
			rt = rt.getGenericType();
		}
		// 拼接 ParameterizedType,并完成 resolve
		ResolvedType type = TypeFactory.createParameterizedType(rt, typeParameterTypes, scope.getWorld());
		if (isGeneric) {
			type = type.getGenericType();
		}
		// UnresolvedType tx = UnresolvedType.forParameterizedTypes(aType,typeParameterTypes);
		// UnresolvedType type = scope.getWorld().resolve(tx,true);
		if (dim != 0) {
			type = ResolvedType.makeArray(type, dim);
		}
		return new ExactTypePattern(type, includeSubtypes, isVarArgs);
	} else {
		// AMC... just leave it as a wild type pattern then?
		importedPrefixes = scope.getImportedPrefixes();
		knownMatches = preMatch(scope.getImportedNames());
		return this;
	}
}
// TypeFactory
public static ReferenceType createParameterizedType(ResolvedType aBaseType, UnresolvedType[] someTypeParameters, World inAWorld) {
	ResolvedType baseType = aBaseType;
	if (!aBaseType.isGenericType()) {
		if (someTypeParameters != null && someTypeParameters.length > 0) {
			if (!aBaseType.isRawType()) {
				throw new IllegalStateException("Expecting raw type, but " + aBaseType+" is of type "+aBaseType.getTypekind());
			}
			// 获取 genericType 作为 baseType
			baseType = baseType.getGenericType();
			if (baseType == null) {
				throw new IllegalStateException("Raw type does not have generic type set");
			}
		} // else if someTypeParameters is null, then the base type is allowed to be non-generic, it's an inner
	}
	ResolvedType[] resolvedParameters = inAWorld.resolve(someTypeParameters);

	// 是否已经存在衍生品
	ReferenceType existingType = ((ReferenceType)baseType).findDerivativeType(resolvedParameters);

	ReferenceType pType = null;

	if (existingType!=null) {
		pType = existingType;
	} else {
		// 创建衍生品
		pType =new ReferenceType(baseType, resolvedParameters, inAWorld);
	}
	// 放入 typeMap
	return (ReferenceType) pType.resolve(inAWorld);
}

public ReferenceType(ResolvedType theGenericType,
		ResolvedType[] theParameters, World aWorld) {
	// 拼接的参数化签名为:"Pjava/util/List<Ljava/lang/String;>;"
	// 泛型擦除后的签名:"Ljava/util/List;"
	super(makeParameterizedSignature(theGenericType, theParameters),
			theGenericType.signatureErasure, aWorld);
	ReferenceType genericReferenceType = (ReferenceType) theGenericType;
	this.typeParameters = theParameters;
	this.genericType = genericReferenceType;
	this.typeKind = TypeKind.PARAMETERIZED;
	this.delegate = genericReferenceType.getDelegate();
	// 将拼接的衍生品作为泛型类型的依赖
	genericReferenceType.addDependentType(this);
}
// 拼接参数化签名
private static String makeParameterizedSignature(ResolvedType aGenericType,
		ResolvedType[] someParameters) {
	// Ljava/util/List;
	String rawSignature = aGenericType.getErasureSignature();
	StringBuffer ret = new StringBuffer();
	ret.append(PARAMETERIZED_TYPE_IDENTIFIER);
	ret.append(rawSignature.substring(1, rawSignature.length() - 1));
	ret.append("<");
	for (ResolvedType someParameter : someParameters) {
		ret.append(someParameter.getSignature());
	}
	ret.append(">;");
	return ret.toString();
}
synchronized void addDependentType(ReferenceType dependent) {
	// 添加依赖
	synchronized (derivativeTypes) {
		this.derivativeTypes
				.add(new WeakReference<>(dependent));
	}
}

从 aBaseType,也就是前面返回的 simpleOrRawType 中获取 genericType 作为 baseType,将类型和泛型实参类型拼接起来,作为 signature,之后封装 ReferenceType,此时 typeKind 为 TypeKind.PARAMETERIZED。

java.util.List<String> 被处理为 "Pjava/util/List<Ljava/lang/String;>;",称之为衍生品。

最后将这个衍生品 ReferenceType 传递给 ExactTypePattern。

这样就完成了泛型类型的类型绑定,解析的时候,将定义类型和泛型参数类型分开,统一封装到 WildTypePattern,之后在类型绑定时,将其具体类型和实际泛型参数类型拼接为一个字符串,封装 ReferenceType,传递给 ExactTypePattern


http://www.kler.cn/a/558228.html

相关文章:

  • 【分治法】线性时间选择问题
  • AWS - Redshift - 外部表读取 Parquet 文件中 timestamp 类型的数据
  • JavaScript函数-函数的使用
  • RNN中远距离时间步梯度消失问题及解决办法
  • 在VSCode中接入deepseek
  • 企业知识管理平台重构数字时代知识体系与智能服务网络
  • Python进行简单医学影像分析的示例
  • 工业大数据实验室解决方案
  • Eclipse2024中文汉化教程(图文版)
  • Ubuntu22 server 安装 Chrome浏览器
  • springboot多实例部署时,@Scheduled注释的方法重复执行
  • 使用FFmpeg将PCMA格式的WAV文件转换为16K采样率的PCM WAV文件
  • Mybatis MyBatis框架的缓存 一级缓存
  • Spring使用三级缓存解决循环依赖的源码分析。
  • AI IDE - Trae -学习与实践
  • git使用-克隆远程项目、分支管理
  • 浅谈小程序内嵌h5分享
  • 【Mysql:数据库的基础操作】
  • Redis 缓存穿透、击穿、雪崩:问题与解决方案
  • 大语言模型:如何用AI快速定制技能,挖掘海量数据的“宝藏”?