启动时如何运行
- 启动时会找到RequestMappingHandlerMapping的afterPropertiesSet运行
- 因为RequestMappingHandlerMapping实现InitializingBean接口,会在bean初始化调用afterPropertiesSet方法,具体源码如下:
// 1
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping ...{
public void afterPropertiesSet() {
this.config = new BuilderConfiguration();
this.config.setUrlPathHelper(this.getUrlPathHelper());
this.config.setPathMatcher(this.getPathMatcher());
this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);
this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);
this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch);
this.config.setContentNegotiationManager(this.getContentNegotiationManager());
super.afterPropertiesSet();
}
}
// 2
public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo>
// 3
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean
- bean是放到哪里的,具体见AbstractHandlerMethodMapping源码:
//1
public void afterPropertiesSet() {
this.initHandlerMethods();
}
//2
protected void initHandlerMethods() {
String[] var1 = this.getCandidateBeanNames();
int var2 = var1.length;
for(int var3 = 0; var3 < var2; ++var3) {
String beanName = var1[var3];
if (!beanName.startsWith("scopedTarget.")) {
this.processCandidateBean(beanName);
}
}
this.handlerMethodsInitialized(this.getHandlerMethods());
}
//3
protected void processCandidateBean(String beanName) {
Class beanType = null;
try {
beanType = this.obtainApplicationContext().getType(beanName);
} catch (Throwable var4) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Could not resolve type for bean '" + beanName + "'", var4);
}
}
if (beanType != null && this.isHandler(beanType)) {
this.detectHandlerMethods(beanName);
}
}
//4
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<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);
});
}
}
//5
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
//6
this.mappingRegistry.register(mapping, handler, method);
}
private final AbstractHandlerMethodMapping<T>.MappingRegistry mappingRegistry = new AbstractHandlerMethodMapping.MappingRegistry();
- 初始化调用afterPropertiesSet
- 调用initHandlerMethods
- 调用processCandidateBean
- 调用detectHandlerMethods
- 调用registerHandlerMethod
- 最终this.mappingRegistry.register(mapping, handler, method);
-
下面再看看AbstractHandlerMethodMapping的register方法,传递的参数如图:
在这里插入图片描述
public void register(T mapping, Object handler, Method method) {
this.readWriteLock.writeLock().lock();//写锁
try {
HandlerMethod handlerMethod = AbstractHandlerMethodMapping.this.createHandlerMethod(handler, method);
this.assertUniqueMethodMapping(handlerMethod, mapping);
this.mappingLookup.put(mapping, handlerMethod);//方法类型和url加入到mappingLookup
List<String> directUrls = this.getDirectUrls(mapping);
Iterator var6 = directUrls.iterator();
while(var6.hasNext()) {
String url = (String)var6.next();
this.urlLookup.add(url, mapping);
}
String name = null;
if (AbstractHandlerMethodMapping.this.getNamingStrategy() != null) {
name = AbstractHandlerMethodMapping.this.getNamingStrategy().getName(handlerMethod, mapping);
this.addMappingName(name, handlerMethod);
}
CorsConfiguration corsConfig = AbstractHandlerMethodMapping.this.initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
this.corsLookup.put(handlerMethod, corsConfig);
}
this.registry.put(mapping, new AbstractHandlerMethodMapping.MappingRegistration(mapping, handlerMethod, directUrls, name));
} finally {
this.readWriteLock.writeLock().unlock();//解锁
}
}
- 所有Controller下方法相关的均的均存入到了MappingRegistry 中,可以自行debug。
class MappingRegistry {
private final Map<T, AbstractHandlerMethodMapping.MappingRegistration<T>> registry = new HashMap();
private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap();
private final MultiValueMap<String, T> urlLookup = new LinkedMultiValueMap();
private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap();
private final Map<HandlerMethod, CorsConfiguration> corsLookup = new ConcurrentHashMap();
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
如:
参考
网友评论