- 浏览: 951855 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
前面我们讲解过DispatcherServlet:http://donald-draper.iteye.com/blog/2325394
Spring-DispatcherServlet请求处理:http://donald-draper.iteye.com/blog/2325415
下面我们来看看DispatcherServlet的handlerMappings初始化所做的事情
//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
查看AbstractDetectingUrlHandlerMapping
查看AbstractUrlHandlerMapping
查看AbstractHandlerMapping
查看WebApplicationObjectSupport
查看ApplicationObjectSupport
好了,看到这里,我们知道一二,再看AbstractDetectingUrlHandlerMapping
查看DefaultAnnotationHandlerMapping
//RequestMapping
再来看registerHandler方法
//注册urls,与beanName的映射
registerHandler(urls, beanName);
//AbstractHandlerMapping
总结:
DefaultAnnotationHandlerMapping主要做的事情是,
将Controller的RequestMapping注解值(类路径及方法路径)与Controller实例映射起来
Spring-DispatcherServlet请求处理:http://donald-draper.iteye.com/blog/2325415
下面我们来看看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(); }
总结:
DefaultAnnotationHandlerMapping主要做的事情是,
将Controller的RequestMapping注解值(类路径及方法路径)与Controller实例映射起来
发表评论
-
Spring的RequestMappingHandlerMapping详解
2016-09-23 08:40 4500深刻理解IdentityHashMap:http://dona ... -
Spring-RequestMappingHandlerAdapter初始化及请求处理
2016-09-22 11:50 10524看这篇文章之前,最好先看下面这篇,以便更好的理解handler ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3042浅谈Spring事务隔离级别:http://www.cnblo ... -
Spring-DispatcherServlet请求处理
2016-09-19 15:42 1644Spring-DispatcherServlet初始化详解:h ... -
Spring-DispatcherServlet初始化详解
2016-09-19 15:03 3636Spring-DispatcherServlet请求处理:ht ... -
Spring上下文加载监听器ContextLoaderListener--源码解析
2016-09-18 18:10 4579一般在web应用配置Spring上下文如下,那么Context ... -
JobDetailFactoryBean与MethodInvokingJobDetailFactoryBean源码分析
2016-09-13 16:07 4180Spring与Quartz集成详解:http://donald ... -
Spring与Quartz集成-源码分析
2016-09-13 11:50 2637在阅读以下文章之前,如果对Quartz任务调度不是很熟悉,请看 ... -
Spring与Quartz集成详解
2016-09-09 17:52 2763首先这个所有的依赖包就不需要多讲了,首先下载Quazrt发布包 ... -
Spring,ApplicationContextAware的作用
2016-08-24 17:38 7引用:http://blog.csdn.net/kaiwii/ ... -
Spring Interceptor
2016-05-31 17:12 530Spring Interceptor相关知识:http://h ... -
基于注解的Spring AOP
2016-05-31 16:05 881Spring AOP 基本概念:http://hotstron ... -
Spring的Task定时器
2016-05-31 10:34 6681.开启注解,定义扫描包 <mvc:annotation ...
相关推荐
Spring Cloud 详解专栏中,对Spring Cloud系列的技术做了介绍及使用方法,通过Spring Cloud 详解专栏,三天就能学习并掌握Spring Cloud技术,投入到项目中使用。笔记记录了Spring Cloud系列技术的介绍及使用方法。
Spring事务详解 Spring事务详解
spring内核详解
spring3 注解 详解spring3 注解 详解spring3 注解 详解
Spring : 春天 —>给软件行业带来了春天 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。 2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。 很难想象Rod ...
spring系统架构与设计模式 java_技术 工作原理 开放源码
spring 注解
spring配置详解spring配置详解spring配置详解spring配置详解spring配置详解spring配置详解spring配置详解
spring框架,技术详解及使用指导spring框架,技术详解及使用指导spring框架,技术详解及使用指导spring框架,技术详解及使用指导spring框架,技术详解及使用指导spring框架,技术详解及使用指导spring框架,技术详解及使用...
本光盘是《整合Struts+Hibernate+Spring应用开发详解》一书的配书光盘,书中的代码按章存放, 即第二章所使用的代码放在codes文件夹的02文件夹下,依次类推。 本光盘根目录下有11个文件夹,其内容和含义说明如下: ...
技术分享:Spring配置详解
spring代理详解.txtspring代理详解.txt
第22天 spring aop详解.docx
java Spring视频详解,非常好,自己学习用的,适合初学者
详细介绍了如何搭建Spring MVC开发环境,以及如何使用springMVC开发系统
spring +hibernate 详解与配置(附图)
一、什么是AOP 二、AOP相关概念 (1)切面 (Aspect) 交叉业务,也就是通用的业务逻辑,比如日志、事务。 (2)通知(Advice) 切面的具体实现 (3)连接点 (Jointpoint) ... Spring AOP:3
spring 所有功能详解spring 所有功能详解spring 所有功能详解
使用Spring 2.5 基于注解驱动的 Spring MVC详解