Spring5 源码阅读笔记(5.2.1)AbstractHandlerMapping 里的 afterPropertiesSet

为什么要看这个方法?

正是这个方法里,完成了从 URL 到处理方法的映射。


类 AbstractHandlerMethodMapping< T >,它实现了 InitializingBean 接口,意味着肯定重写了 afterPropertiesSet 方法,跟 afterPropertiesSet

另外 AbstractHandlerMethodMapping< T > 里有一个很重要的内部类:
在这里插入图片描述

  • urlLookup:URI 和 LinkedList< RequestMappingInfo > 的映射关系
  • mappingLookup:RequestMappingInfo(@RequestMapping信息) 和 HandlerMethod(处理方法)的映射关系

5.2.1 afterPropertiesSet

Spring 启动的时候完成从 url 到方法的映射

@Override
public void afterPropertiesSet() {
	initHandlerMethods();
}

跟 initHandlerMethods:

protected void initHandlerMethods() {
	for (String beanName : getCandidateBeanNames()) {
		if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
			processCandidateBean(beanName);
		}
	}
	handlerMethodsInitialized(getHandlerMethods());
}

跟 processCandidateBean:

protected void processCandidateBean(String beanName) {
	Class<?> beanType = null;
	try {
		beanType = obtainApplicationContext().getType(beanName);
	}
	catch (Throwable ex) {
		// An unresolvable bean type, probably from a lazy bean - let's ignore it.
		if (logger.isTraceEnabled()) {
			logger.trace("Could not resolve type for bean '" + beanName + "'", ex);
		}
	}
							//如果类上面有@Controller注解或者@RequestMapping注解
	if (beanType != null && isHandler(beanType)) {
		//建立uri和method的映射关系
		detectHandlerMethods(beanName);
	}
}

跟 detectHandlerMethods:

										//被@Controller或者@RequestMapping注解的类名
protected void detectHandlerMethods(Object handler) {
	Class<?> handlerType = (handler instanceof String ?
			obtainApplicationContext().getType((String) handler) : handler.getClass());

	if (handlerType != null) {
		Class<?> userType = ClassUtils.getUserClass(handlerType);

		//获取方法对象和方法上面的@RequestMapping注解属性封装对象的映射关系 
		//         T : RequestMappingInfo            5.2.1.2
		Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
				(MethodIntrospector.MetadataLookup<T>) method -> {
					try {
								//5.2.1.1
						return getMappingForMethod(method, userType);
					}
					catch (Throwable ex) {
						throw new IllegalStateException("Invalid mapping on handler class [" +
								userType.getName() + "]: " + method, ex);
					}
				});
		if (logger.isTraceEnabled()) {
			logger.trace(formatMappings(userType, methods));
		}
		methods.forEach((method, mapping) -> {
			Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
			//建立uri和方法的各种映射关系,根据uri要能够找到method对象 5.2.1.3
			registerHandlerMethod(handler, invocableMethod, mapping);
		});
	}
}
5.2.1.1 getMappingForMethod

类 RequestMappingHandlerMapping

@Override
@Nullable									//被@RequestMapping注解的方法     被注解的类
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
	//寻找有@RequestMapping注解的方法,然后注解里面的属性封装成对象
	RequestMappingInfo info = createRequestMappingInfo(method);
	if (info != null) {
		//类上面的@RequestMapping注解也封装成对象
		RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
		if (typeInfo != null) {
			//把方法上面的注解属性结合到类上面的RequestMappingInfo对象中
			info = typeInfo.combine(info);
		}
		String prefix = getPathPrefix(handlerType);
		if (prefix != null) {
			info = RequestMappingInfo.paths(prefix).build().combine(info);
		}
	}
	return info;
}
5.2.1.2 selectMethods
public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) {
	final Map<Method, T> methodMap = new LinkedHashMap<>();
	Set<Class<?>> handlerTypes = new LinkedHashSet<>();
	Class<?> specificHandlerType = null;

	if (!Proxy.isProxyClass(targetType)) {
		specificHandlerType = ClassUtils.getUserClass(targetType);
		//加上自己
		handlerTypes.add(specificHandlerType);
	}
	//加上自己实现的接口
	handlerTypes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetType));

	for (Class<?> currentHandlerType : handlerTypes) {
		final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);

		//循环currentHandlerType类的所有方法
		ReflectionUtils.doWithMethods(currentHandlerType, method -> {
			Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
			//判断方法上面是否有@RequestMapping注解,如果有封装成RequestMappingInfo对象返回 见上面代码块的匿名方法
			T result = metadataLookup.inspect(specificMethod);
			if (result != null) {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
																	
				if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {
					//建立方法对象和注解封装对象的映射关系
					methodMap.put(specificMethod, result);
				}
			}
		}, ReflectionUtils.USER_DECLARED_METHODS);
	}

	return methodMap;
}

跟 doWithMethods:

public static void doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf) {
	// Keep backing up the inheritance hierarchy.
	//所有有@RequestMapping的方法
	Method[] methods = getDeclaredMethods(clazz);
	for (Method method : methods) {
		if (mf != null && !mf.matches(method)) {
			continue;
		}
		try {
				//见上面代码块的匿名方法
			mc.doWith(method);
		}
		catch (IllegalAccessException ex) {
			throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);
		}
	}
	if (clazz.getSuperclass() != null) {
		doWithMethods(clazz.getSuperclass(), mc, mf);
	}
	else if (clazz.isInterface()) {
		for (Class<?> superIfc : clazz.getInterfaces()) {
			doWithMethods(superIfc, mc, mf);
		}
	}
}
5.2.1.3 registerHandlerMethod
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
	this.mappingRegistry.register(mapping, handler, method);
}

跟 register:

public void register(T mapping, Object handler, Method method) {
	this.readWriteLock.writeLock().lock();
	try {
		//创建HandlerMethod对象
		HandlerMethod handlerMethod = createHandlerMethod(handler, method);
		//检验是否唯一
		assertUniqueMethodMapping(handlerMethod, mapping);
		//建立RequestMappingInfo和handlerMethod的映射关系
		this.mappingLookup.put(mapping, handlerMethod);

		List<String> directUrls = getDirectUrls(mapping);
		for (String url : directUrls) {
			//建立url(uri)和RequestMappingInfo映射关系
			this.urlLookup.add(url, mapping);
		}

		String name = null;
		if (getNamingStrategy() != null) {
			name = getNamingStrategy().getName(handlerMethod, mapping);
			addMappingName(name, handlerMethod);
		}

		//判断method上是否有@CrossOrigin注解,把注解里面的属性封装成CorsConfiguration,这个是做跨域访问控制的
		CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
		if (corsConfig != null) {
			//建立映射关系
			this.corsLookup.put(handlerMethod, corsConfig);
		}

		this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
	}
	finally {
		this.readWriteLock.writeLock().unlock();
	}
}

跟 createHandlerMethod:

protected HandlerMethod createHandlerMethod(Object handler, Method method) {
	HandlerMethod handlerMethod;
	//如果是被注解的类名
	if (handler instanceof String) {
		String beanName = (String) handler;
		handlerMethod = new HandlerMethod(beanName,
				obtainApplicationContext().getAutowireCapableBeanFactory(), method);
	}
	else {
		handlerMethod = new HandlerMethod(handler, method);
	}
	return handlerMethod;
}
发布了185 篇原创文章 · 获赞 271 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44367006/article/details/104936823