Spring容器初始化过程中,在调用prepareBeanFactory方法时,会调用所有实现了ApplicationContextAware接口的子类方法setApplicationContext()方法注入ApplicationContext对象。ApplicationObjectSupport类是ApplicationContextAware接口的子类,它的setApplicationContext()如下:
public final void setApplicationContext(ApplicationContext context) throws BeansException {
if (context == null && !isContextRequired()) {
this.applicationContext = null;
this.messageSourceAccessor = null;
}
else if (this.applicationContext == null) {
this.applicationContext = context;
this.messageSourceAccessor = new MessageSourceAccessor(context);
initApplicationContext(context);
}
}
protected void initApplicationContext(ApplicationContext context) throws BeansException {
initApplicationContext();
}
做了一次转换后,真正去调用子类中initApplicationContext()方法的实现。我们需要关心的是子类SimpleUrlHandlerMapping对它的实现:
public void initApplicationContext() throws BeansException {
super.initApplicationContext();
registerHandlers(this.urlMap);
}
其中super.initApplicationContext()方法在父类AbstractHandlerMapping中,如下:
protected void initApplicationContext() throws BeansException {
extendInterceptors(this.interceptors);
detectMappedInterceptors(this.mappedInterceptors);
//初始化所有拦截器
initInterceptors();
}
注册控制器的方法在SimpleUrlHandlerMapping类中,如下:
protected void registerHandlers(Map<String, Object> urlMap) throws BeansException {
if (urlMap.isEmpty()) {
logger.warn("Neither 'urlMap' nor 'mappings' set on SimpleUrlHandlerMapping");
}
else {
for (Map.Entry<String, Object> entry : urlMap.entrySet()) {
String url = entry.getKey();
Object handler = entry.getValue();
// Prepend with slash if not already present.
if (!url.startsWith("/")) {
url = "/" + url;
}
// Remove whitespace from handler bean name.
if (handler instanceof String) {
handler = ((String) handler).trim();
}
registerHandler(url, handler);
}
}
}
AbstractUrlHandlerMapping类中的registerHandler()方法
protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
Assert.notNull(urlPath, "URL path must not be null");
Assert.notNull(handler, "Handler object must not be null");
Object resolvedHandler = handler;
// Eagerly resolve handler if referencing singleton via name.
if (!this.lazyInitHandlers && handler instanceof String) {
String handlerName = (String) handler;
if (getApplicationContext().isSingleton(handlerName)) {
resolvedHandler = getApplicationContext().getBean(handlerName);
}
}
Object mappedHandler = this.handlerMap.get(urlPath);
if (mappedHandler != null) {
if (mappedHandler != resolvedHandler) {
throw new IllegalStateException(
"Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath +
"]: There is already " + getHandlerDescription(mappedHandler) + " mapped.");
}
}
else {
if (urlPath.equals("/")) {
if (logger.isInfoEnabled()) {
logger.info("Root mapping to " + getHandlerDescription(handler));
}
setRootHandler(resolvedHandler);
}
else if (urlPath.equals("/*")) {
if (logger.isInfoEnabled()) {
logger.info("Default mapping to " + getHandlerDescription(handler));
}
setDefaultHandler(resolvedHandler);
}
else {
this.handlerMap.put(urlPath, resolvedHandler);
if (logger.isInfoEnabled()) {
logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler));
}
}
}
}
需要注意的是这行代码:
this.handlerMap.put(urlPath, resolvedHandler);
它把我们的handler保存到了map容器中。