@RequestMapping可以声明类和方法对应的URL路径, 这些对应关系被注册在HandlerMapping中, 本文通过源码分析注册过程
注册过程的具体实现主要在RequestMappingHandlerMapping类中, 该类实现了InilizationBean接口中的afterPropertiesSet()接口, 调用其父类的该方法实现中完成加载.
processCandidateBean()中对候选进行筛选, 并检测其所有方法
protected void processCandidateBean(String beanName) {
Class beanType = null;
// 获取Bean的类型
try {
beanType = this.obtainApplicationContext().getType(beanName);
} catch (Throwable var4) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Could not resolve type for bean '" + beanName + "'", var4);
}
}
// Bean为Controller,则探测其所有方法
if (beanType != null && this.isHandler(beanType)) {
this.detectHandlerMethods(beanName);
}
}
s
protected void detectHandlerMethods(Object handler) {
Class<?> handlerType = handler instanceof String ? this.obtainApplicationContext().getType((String)handler) : handler.getClass();
if (handlerType != null) {
Class<?> userType = ClassUtils.getUserClass(handlerType);
// 获取方法并检验合法性, 按方法名->路径保存在Map中
Map<Method, T> methods = MethodIntrospector.selectMethods(userType, (method) -> {
try {
return this.getMappingForMethod(method, userType);
} catch (Throwable var4) {
throw new IllegalStateException("Invalid mapping on handler class [" + userType.getName() + "]: " + method, var4);
}
});
if (this.logger.isTraceEnabled()) {
this.logger.trace(this.formatMappings(userType, methods));
}
// 注册
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
this.registerHandlerMethod(handler, invocableMethod, mapping);
});
}
}
最终被注册到一个map中, key->value如下