Spring的DefaultAnnotationHandlerMapping详解

前面我们讲解过DispatcherServlet:[url]http://donald-draper.iteye.com/blog/2325394[/url]
Spring-DispatcherServlet请求处理:[url]http://donald-draper.iteye.com/blog/2325415[/url]
下面我们来看看DispatcherServlet的handlerMappings初始化所做的事情
public class DispatcherServlet extends FrameworkServlet
{
public DispatcherServlet(WebApplicationContext webApplicationContext)
{
super(webApplicationContext);
detectAllHandlerMappings = true;
detectAllHandlerAdapters = true;
detectAllHandlerExceptionResolvers = true;
detectAllViewResolvers = true;
throwExceptionIfNoHandlerFound = false;
cleanupAfterInclude = true;
}

//初始化控制器映射
private void initHandlerMappings(ApplicationContext context)
{
handlerMappings = null;
if(detectAllHandlerMappings)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerMapping, true, false);
if(!matchingBeans.isEmpty())
{
//List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例
handlerMappings = new ArrayList(matchingBeans.values());
OrderComparator.sort(handlerMappings);
}
}
}
//初始化控制器方法适配器
private void initHandlerAdapters(ApplicationContext context)
{
handlerAdapters = null;
if(detectAllHandlerAdapters)
{
Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerAdapter, true, false);
if(!matchingBeans.isEmpty())
{
//List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例
handlerAdapters = new ArrayList(matchingBeans.values());
OrderComparator.sort(handlerAdapters);
}
}
}

private List handlerMappings;//List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例
private List handlerAdapters;//List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例
private List handlerExceptionResolvers;
private List viewResolvers;

static
{
try
{
//加载默认配置文件
ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", org/springframework/web/servlet/DispatcherServlet);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
}
}

//Spring日志追踪我们可以发现,DispatcherServletd的控制器映射处理器为
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
//静态文件的映射js,css等
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
这里我们来讲默认注解控制器映射处理器DefaultAnnotationHandlerMapping
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping
{

public DefaultAnnotationHandlerMapping()
{
useDefaultSuffixPattern = true;
}

public void setUseDefaultSuffixPattern(boolean useDefaultSuffixPattern)
{
this.useDefaultSuffixPattern = useDefaultSuffixPattern;
}
//这里我们找不到任何头绪
}

查看AbstractDetectingUrlHandlerMapping
public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping
{

public AbstractDetectingUrlHandlerMapping()
{
detectHandlersInAncestorContexts = false;
}

public void setDetectHandlersInAncestorContexts(boolean detectHandlersInAncestorContexts)
{
this.detectHandlersInAncestorContexts = detectHandlersInAncestorContexts;
}
//初始化应用上下文,这里好像有点头绪
public void initApplicationContext()
throws ApplicationContextException
{
//查看父类
super.initApplicationContext();
detectHandlers();
}
}

查看AbstractUrlHandlerMapping
public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping
{
//没有任何迹象
}

查看AbstractHandlerMapping
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
implements HandlerMapping, Ordered
{
//貌似有点头绪
protected void initApplicationContext()
throws BeansException
{
extendInterceptors(interceptors);
detectMappedInterceptors(mappedInterceptors);
//初始化拦截器
initInterceptors();
}
}

查看WebApplicationObjectSupport
public abstract class WebApplicationObjectSupport extends ApplicationObjectSupport
implements ServletContextAware
{
//还是没看到怎么回事
protected void initApplicationContext(ApplicationContext context)
{
super.initApplicationContext(context);
if(servletContext == null && (context instanceof WebApplicationContext))
{
servletContext = ((WebApplicationContext)context).getServletContext();
if(servletContext != null)
initServletContext(servletContext);
}
}
protected void initServletContext(ServletContext servletcontext)
{
}
}

查看ApplicationObjectSupport
public abstract class ApplicationObjectSupport
implements ApplicationContextAware
{
public final void setApplicationContext(ApplicationContext context)
throws BeansException
{
if(context == null && !isContextRequired())
{
applicationContext = null;
messageSourceAccessor = null;
} else
if(applicationContext == null)
{ //关键,是不是有点意思了
initApplicationContext(context);
}
}
protected void initApplicationContext(ApplicationContext context)
throws BeansException
{
initApplicationContext();
}
//留给子类扩展
protected void initApplicationContext()
throws BeansException
{
}
}

好了,看到这里,我们知道一二,再看AbstractDetectingUrlHandlerMapping
public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping
{

public AbstractDetectingUrlHandlerMapping()
{
detectHandlersInAncestorContexts = false;
}

public void setDetectHandlersInAncestorContexts(boolean detectHandlersInAncestorContexts)
{
this.detectHandlersInAncestorContexts = detectHandlersInAncestorContexts;
}
//初始化应用上下文,
public void initApplicationContext()
throws ApplicationContextException
{
//初始化父类应用上下文
super.initApplicationContext();
//探测Handlers
detectHandlers();
}
protected void detectHandlers()
throws BeansException
{
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Looking for URL mappings in application context: ").append(getApplicationContext()).toString());
String beanNames[] = detectHandlersInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), java/lang/Object) : getApplicationContext().getBeanNamesForType(java/lang/Object);
String as[] = beanNames;
int i = as.length;
for(int j = 0; j < i; j++)
{
String beanName = as[j];
//获取处理器的urls
String urls[] = determineUrlsForHandler(beanName);
if(!ObjectUtils.isEmpty(urls))
{
//注册urls,与beanName的映射
registerHandler(urls, beanName);
continue;
}
}

}
//获取处理器的urls,父类扩展
protected abstract String[] determineUrlsForHandler(String s);
}

查看DefaultAnnotationHandlerMapping
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping
{

protected String[] determineUrlsForHandler(String beanName)
{
ApplicationContext context = getApplicationContext();
Class handlerType = context.getType(beanName);
//获取beanName的@RequestMapping
RequestMapping mapping = (RequestMapping)context.findAnnotationOnBean(beanName, org/springframework/web/bind/annotation/RequestMapping);
if(mapping != null)
{
cachedMappings.put(handlerType, mapping);
Set urls = new LinkedHashSet();
String typeLevelPatterns[] = mapping.value();
if(typeLevelPatterns.length > 0)
{
//获取Controller方法urls
String methodLevelPatterns[] = determineUrlsForHandlerMethods(handlerType, true);
String as[] = typeLevelPatterns;
int i = as.length;
for(int j = 0; j < i; j++)
{
String typeLevelPattern = as[j];
//不以/开头,添加/
if(!typeLevelPattern.startsWith("/"))
typeLevelPattern = (new StringBuilder()).append("/").append(typeLevelPattern).toString();
boolean hasEmptyMethodLevelMappings = false;
String as1[] = methodLevelPatterns;
int k = as1.length;
for(int l = 0; l < k; l++)
{
String methodLevelPattern = as1[l];
if(methodLevelPattern == null)
{
hasEmptyMethodLevelMappings = true;
} else
{
String combinedPattern = getPathMatcher().combine(typeLevelPattern, methodLevelPattern);
addUrlsForPath(urls, combinedPattern);
}
}
//bean带@Controller注解添加Path到urls
if(hasEmptyMethodLevelMappings || org/springframework/web/servlet/mvc/Controller.isAssignableFrom(handlerType))
addUrlsForPath(urls, typeLevelPattern);
}
return StringUtils.toStringArray(urls);
} else
{
return determineUrlsForHandlerMethods(handlerType, false);
}
}
if(AnnotationUtils.findAnnotation(handlerType, org/springframework/stereotype/Controller) != null)
return determineUrlsForHandlerMethods(handlerType, false);
else
return null;
}
//获取方法urls
protected String[] determineUrlsForHandlerMethods(Class handlerType, final boolean hasTypeLevelMapping)
{
String subclassResult[] = determineUrlsForHandlerMethods(handlerType);
if(subclassResult != null)
return subclassResult;
final Set urls = new LinkedHashSet();
Set handlerTypes = new LinkedHashSet();
handlerTypes.add(handlerType);
handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces()));
Class currentHandlerType;
for(Iterator iterator = handlerTypes.iterator(); iterator.hasNext(); ReflectionUtils.doWithMethods(currentHandlerType, new org.springframework.util.ReflectionUtils.MethodCallback() {
public void doWith(Method method)
{
//获取bean方法method的@RequestMapping
RequestMapping mapping = (RequestMapping)AnnotationUtils.findAnnotation(method, org/springframework/web/bind/annotation/RequestMapping);
if(mapping != null)
{
String mappedPatterns[] = mapping.value();
if(mappedPatterns.length > 0)
{
String as[] = mappedPatterns;
int i = as.length;
for(int j = 0; j < i; j++)
{
String mappedPattern = as[j];
//不以/开头,添加/
if(!hasTypeLevelMapping && !mappedPattern.startsWith("/"))
mappedPattern = (new StringBuilder()).append("/").append(mappedPattern).toString();
//添加method的Path到urls
addUrlsForPath(urls, mappedPattern);
}

} else
if(hasTypeLevelMapping)
urls.add(null);
}
}

final boolean val$hasTypeLevelMapping;
final Set val$urls;
final DefaultAnnotationHandlerMapping this$0;


{
this.this$0 = DefaultAnnotationHandlerMapping.this;
hasTypeLevelMapping = flag;
urls = set;
super();
}
}, ReflectionUtils.USER_DECLARED_METHODS))
currentHandlerType = (Class)iterator.next();

return StringUtils.toStringArray(urls);
}
//默认返回的urls为null
protected String[] determineUrlsForHandlerMethods(Class handlerType)
{
return null;
}
//添加path到urls-set
protected void addUrlsForPath(Set urls, String path)
{
urls.add(path);
if(useDefaultSuffixPattern && path.indexOf('.') == -1 && !path.endsWith("/"))
{
urls.add((new StringBuilder()).append(path).append(".*").toString());
urls.add((new StringBuilder()).append(path).append("/").toString());
}
}
private final Map cachedMappings = new HashMap();//HashMap<Class,RequestMapping>,key为Controller类,value为RequestMapping
}

//RequestMapping
public interface RequestMapping
extends Annotation
{
public abstract String[] value();
public abstract RequestMethod[] method();
public abstract String[] params();
public abstract String[] headers();
public abstract String[] consumes();
public abstract String[] produces();
}

再来看registerHandler方法
//注册urls,与beanName的映射
registerHandler(urls, beanName);
public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping
{
//注册urlPaths,与beanName的映射
protected void registerHandler(String urlPaths[], String beanName)
throws BeansException, IllegalStateException
{
Assert.notNull(urlPaths, "URL path array must not be null");
String as[] = urlPaths;
int i = as.length;
for(int j = 0; j < i; j++)
{
String urlPath = as[j];
registerHandler(urlPath, beanName);
}

}
//注册urlPath,与beanName的映射
protected void registerHandler(String urlPath, Object handler)
throws BeansException, IllegalStateException
{

Object resolvedHandler = handler;
if(!lazyInitHandlers && (handler instanceof String))
{
String handlerName = (String)handler;
if(getApplicationContext().isSingleton(handlerName))
//获取bean实例,实际Controller实例
resolvedHandler = getApplicationContext().getBean(handlerName);
}
Object mappedHandler = handlerMap.get(urlPath);
if(mappedHandler != null)
{
//如果urlPath已经存在,抛出异常
if(mappedHandler != resolvedHandler)
throw new IllegalStateException((new StringBuilder()).append("Cannot map ").append(getHandlerDescription(handler)).append(" to URL path [").append(urlPath).append("]: There is already ").append(getHandlerDescription(mappedHandler)).append(" mapped.").toString());
} else
if(urlPath.equals("/"))
{
if(logger.isInfoEnabled())
logger.info((new StringBuilder()).append("Root mapping to ").append(getHandlerDescription(handler)).toString());
//如果以/开头设为根处理器
setRootHandler(resolvedHandler);
} else
if(urlPath.equals("/*"))
{
if(logger.isInfoEnabled())
logger.info((new StringBuilder()).append("Default mapping to ").append(getHandlerDescription(handler)).toString());
//如果以/开头设为默认处理器
setDefaultHandler(resolvedHandler);
} else
{
//添加url路径与Handler映射到handlerMap
handlerMap.put(urlPath, resolvedHandler);
if(logger.isInfoEnabled())
logger.info((new StringBuilder()).append("Mapped URL path [").append(urlPath).append("] onto ").append(getHandlerDescription(handler)).toString());
}
}
//设置根处理器
public void setRootHandler(Object rootHandler)
{
this.rootHandler = rootHandler;
}
//根据urlPath,寻找Handler
protected Object lookupHandler(String urlPath, HttpServletRequest request)
throws Exception
{
Object handler = handlerMap.get(urlPath);
if(handler != null)
{
if(handler instanceof String)
{
String handlerName = (String)handler;
handler = getApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
return buildPathExposingHandler(handler, urlPath, urlPath, null);
}
List matchingPatterns = new ArrayList();
String bestPatternMatch = handlerMap.keySet().iterator();
do
{
if(!bestPatternMatch.hasNext())
break;
String registeredPattern = (String)bestPatternMatch.next();
if(getPathMatcher().match(registeredPattern, urlPath))
matchingPatterns.add(registeredPattern);
} while(true);
bestPatternMatch = null;
Comparator patternComparator = getPathMatcher().getPatternComparator(urlPath);
if(!matchingPatterns.isEmpty())
{
Collections.sort(matchingPatterns, patternComparator);
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("Matching patterns for request [").append(urlPath).append("] are ").append(matchingPatterns).toString());
bestPatternMatch = (String)matchingPatterns.get(0);
}
if(bestPatternMatch != null)
{
handler = handlerMap.get(bestPatternMatch);
if(handler instanceof String)
{
String handlerName = (String)handler;
handler = getApplicationContext().getBean(handlerName);
}
validateHandler(handler, request);
String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);
Map uriTemplateVariables = new LinkedHashMap();
Iterator iterator = matchingPatterns.iterator();
do
{
if(!iterator.hasNext())
break;
String matchingPattern = (String)iterator.next();
if(patternComparator.compare(bestPatternMatch, matchingPattern) == 0)
{
Map vars = getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath);
Map decodedVars = getUrlPathHelper().decodePathVariables(request, vars);
uriTemplateVariables.putAll(decodedVars);
}
} while(true);
if(logger.isDebugEnabled())
logger.debug((new StringBuilder()).append("URI Template variables for request [").append(urlPath).append("] are ").append(uriTemplateVariables).toString());
return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
} else
{
return null;
}
}
private Object rootHandler;
private boolean lazyInitHandlers;
private final Map handlerMap = new LinkedHashMap();//LinkedHashMap<String,Object>,key为urlPath,value为对应的handler
}

//AbstractHandlerMapping
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
implements HandlerMapping, Ordered
{
//设置默认Handler
public void setDefaultHandler(Object defaultHandler)
{
this.defaultHandler = defaultHandler;
}
private int order;
private Object defaultHandler;
private UrlPathHelper urlPathHelper;
private PathMatcher pathMatcher;
private final List interceptors = new ArrayList();
private final List adaptedInterceptors = new ArrayList();
private final List mappedInterceptors = new ArrayList();
}

总结:
[color=blue]DefaultAnnotationHandlerMapping主要做的事情是,
将Controller的RequestMapping注解值(类路径及方法路径)与Controller实例映射起来
[/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值