- 浏览: 979792 次
文章分类
- 全部博客 (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)
深刻理解IdentityHashMap:http://donald-draper.iteye.com/blog/2326264
深入理解Collections的unmodifiableMap(Map map)方法:http://donald-draper.iteye.com/blog/2326291
Spring-RequestMappingHandlerAdapter初始化及请求处理:http://donald-draper.iteye.com/blog/2326185
我们来看DispatcherServlet的handlerMappings初始化所做的事情
//Spring日志追踪我们可以发现,DispatcherServletd的控制器映射处理器为
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
这里我们来看RequestMappingHandlerMapping
查看RequestMappingHandlerMapping.isHandler()
//isHandler,判断bean是否带有@Controller
查看RequestMappingHandlerMapping.getMappingForMethod()
//判断handlerType的method是否带@RequestMapping,并返回注解信息
查看RequestMappingInfoHandlerMapping.getMappingPathPatterns()
//RequestMappingInfo
查看PatternsRequestCondition
//RequestMappingInfo
查看PatternsRequestCondition
总结:
从以上分析,可以看出RequestMappingHandlerMapping,主要做的工作是将Contoller的带RequestMapping方法,添加到处理方法映射器和路径方法解决器中。
深入理解Collections的unmodifiableMap(Map map)方法:http://donald-draper.iteye.com/blog/2326291
Spring-RequestMappingHandlerAdapter初始化及请求处理:http://donald-draper.iteye.com/blog/2326185
我们来看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.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
这里我们来看RequestMappingHandlerMapping
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping implements EmbeddedValueResolverAware { //初始化 public void afterPropertiesSet() { if(useRegisteredSuffixPatternMatch) fileExtensions.addAll(contentNegotiationManager.getAllFileExtensions()); //调用父类的初始化 super.afterPropertiesSet(); } private boolean useSuffixPatternMatch; private boolean useRegisteredSuffixPatternMatch; private boolean useTrailingSlashMatch; private ContentNegotiationManager contentNegotiationManager; private final List fileExtensions = new ArrayList(); private StringValueResolver embeddedValueResolver; } 来查看AbstractHandlerMethodMapping public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping implements InitializingBean { //初始化 public void afterPropertiesSet() { //委托给initHandlerMethods initHandlerMethods(); } //初始化方法处理器 protected void initHandlerMethods() { //获取所有bean容器的beanName String beanNames[] = detectHandlerMethodsInAncestorContexts ? 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]; //如果bean为Controller if(!beanName.startsWith("scopedTarget.") && isHandler(getApplicationContext().getType(beanName))) // detectHandlerMethods(beanName); } handlerMethodsInitialized(getHandlerMethods()); } //获取方法处理器Map public Map getHandlerMethods() { //返回一个不可修改的Map集 return Collections.unmodifiableMap(handlerMethods); } //留给子类扩展 protected void handlerMethodsInitialized(Map map) { } //委托给RequestMappingHandlerMapping protected abstract boolean isHandler(Class class1); //将handler带@RequestMapping的方法添加到方法处理器Map中handlerMethods,及路径映射Map中urlMap protected void detectHandlerMethods(Object handler) { Class handlerType = (handler instanceof String) ? getApplicationContext().getType((String)handler) : handler.getClass(); //注意这里用的是IdentityHashMap final Map mappings = new IdentityHashMap(); final Class userType = ClassUtils.getUserClass(handlerType); //获取Contoller所有带@RequestMapping的方法 Set methods = HandlerMethodSelector.selectMethods(userType, new org.springframework.util.ReflectionUtils.MethodFilter() { public boolean matches(Method method) { //获取handlerType的method的@RequestMapping注解信息 Object mapping = getMappingForMethod(method, userType); if(mapping != null) { mappings.put(method, mapping); return true; } else { return false; } } final Class val$userType; final Map val$mappings; final AbstractHandlerMethodMapping this$0; { this.this$0 = AbstractHandlerMethodMapping.this; userType = class1; mappings = map; super(); } }); Method method; for(Iterator iterator = methods.iterator(); iterator.hasNext(); registerHandlerMethod(handler, method, mappings.get(method))) method = (Method)iterator.next(); } protected void registerHandlerMethod(Object handler, Method method, Object mapping) { //创建方法处理器 HandlerMethod newHandlerMethod = createHandlerMethod(handler, method); //从handlerMethods中获取方法处理器信息根据@RequestMapping注解信息 HandlerMethod oldHandlerMethod = (HandlerMethod)handlerMethods.get(mapping); //如果已经存在,则抛出不能映射异常 if(oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) throw new IllegalStateException((new StringBuilder()).append("Ambiguous mapping found. Cannot map '").append(newHandlerMethod.getBean()).append("' bean method \n").append(newHandlerMethod).append("\nto ").append(mapping).append(": There is already '").append(oldHandlerMethod.getBean()).append("' bean method\n").append(oldHandlerMethod).append(" mapped.").toString()); //将方法处理器放入handlerMethods中 handlerMethods.put(mapping, newHandlerMethod); if(logger.isInfoEnabled()) logger.info((new StringBuilder()).append("Mapped \"").append(mapping).append("\" onto ").append(newHandlerMethod).toString()); //获取路径集 Set patterns = getMappingPathPatterns(mapping); Iterator iterator = patterns.iterator(); do { if(!iterator.hasNext()) break; String pattern = (String)iterator.next(); if(!getPathMatcher().isPattern(pattern)) //将路径与mapping关联 urlMap.add(pattern, mapping); } while(true); } //委托给RequestMappingInfoHandlerMapping protected abstract Object getMappingForMethod(Method method, Class class1); protected abstract Set getMappingPathPatterns(Object obj); //根据request的url寻找合适的HandlerMethod protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Looking up handler method for path ").append(lookupPath).toString()); //根据路径和request寻找handlerMethod HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); if(logger.isDebugEnabled()) if(handlerMethod != null) logger.debug((new StringBuilder()).append("Returning handler method [").append(handlerMethod).append("]").toString()); else logger.debug((new StringBuilder()).append("Did not find handler method for [").append(lookupPath).append("]").toString()); return handlerMethod == null ? null : handlerMethod.createWithResolvedBean(); } //根据路径和request寻找handlerMethod protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception { List matches = new ArrayList(); List directPathMatches = (List)urlMap.get(lookupPath); if(directPathMatches != null) addMatchingMappings(directPathMatches, matches, request); if(matches.isEmpty()) addMatchingMappings(handlerMethods.keySet(), matches, request); if(!matches.isEmpty()) { Comparator comparator = new MatchComparator(getMappingComparator(request)); Collections.sort(matches, comparator); if(logger.isTraceEnabled()) logger.trace((new StringBuilder()).append("Found ").append(matches.size()).append(" matching mapping(s) for [").append(lookupPath).append("] : ").append(matches).toString()); Match bestMatch = (Match)matches.get(0); if(matches.size() > 1) { Match secondBestMatch = (Match)matches.get(1); if(comparator.compare(bestMatch, secondBestMatch) == 0) { Method m1 = bestMatch.handlerMethod.getMethod(); Method m2 = secondBestMatch.handlerMethod.getMethod(); throw new IllegalStateException((new StringBuilder()).append("Ambiguous handler methods mapped for HTTP path '").append(request.getRequestURL()).append("': {").append(m1).append(", ").append(m2).append("}").toString()); } } handleMatch(bestMatch.mapping, lookupPath, request); return bestMatch.handlerMethod; } else { return handleNoMatch(handlerMethods.keySet(), lookupPath, request); } } private static final String SCOPED_TARGET_NAME_PREFIX = "scopedTarget."; private boolean detectHandlerMethodsInAncestorContexts; //LinkedHashMap<RequestMappingInfo,HandlerMethod> private final Map handlerMethods = new LinkedHashMap(); /LinkedHashMap<String,RequestMappingInfo>,key为路径 private final MultiValueMap urlMap = new LinkedMultiValueMap(); }
查看RequestMappingHandlerMapping.isHandler()
//isHandler,判断bean是否带有@Controller
protected boolean isHandler(Class beanType) { return AnnotationUtils.findAnnotation(beanType, org/springframework/stereotype/Controller) != null || AnnotationUtils.findAnnotation(beanType, org/springframework/web/bind/annotation/RequestMapping) != null; }
查看RequestMappingHandlerMapping.getMappingForMethod()
protected volatile Object getMappingForMethod(Method method, Class class1) { return getMappingForMethod(method, class1); }
//判断handlerType的method是否带@RequestMapping,并返回注解信息
protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { RequestMappingInfo info = null; RequestMapping methodAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(method, org/springframework/web/bind/annotation/RequestMapping); if(methodAnnotation != null) { RequestCondition methodCondition = getCustomMethodCondition(method); info = createRequestMappingInfo(methodAnnotation, methodCondition); RequestMapping typeAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(handlerType, org/springframework/web/bind/annotation/RequestMapping); if(typeAnnotation != null) { RequestCondition typeCondition = getCustomTypeCondition(handlerType); info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info); } } return info; }
查看RequestMappingInfoHandlerMapping.getMappingPathPatterns()
public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping { protected Set getMappingPathPatterns(RequestMappingInfo info) { return info.getPatternsCondition().getPatterns(); } }
//RequestMappingInfo
public final class RequestMappingInfo implements RequestCondition { public PatternsRequestCondition getPatternsCondition() { return patternsCondition; } private final PatternsRequestCondition patternsCondition; private final RequestMethodsRequestCondition methodsCondition; private final ParamsRequestCondition paramsCondition; private final HeadersRequestCondition headersCondition; private final ConsumesRequestCondition consumesCondition; private final ProducesRequestCondition producesCondition; private final RequestConditionHolder customConditionHolder; }
查看PatternsRequestCondition
public final class PatternsRequestCondition extends AbstractRequestCondition { public Set getPatterns() { return patterns; } private final Set patterns; private final UrlPathHelper pathHelper; private final PathMatcher pathMatcher; private final boolean useSuffixPatternMatch; private final boolean useTrailingSlashMatch; private final List fileExtensions; }
//RequestMappingInfo
public final class RequestMappingInfo implements RequestCondition { public PatternsRequestCondition getPatternsCondition() { return patternsCondition; } private final PatternsRequestCondition patternsCondition; private final RequestMethodsRequestCondition methodsCondition; private final ParamsRequestCondition paramsCondition; private final HeadersRequestCondition headersCondition; private final ConsumesRequestCondition consumesCondition; private final ProducesRequestCondition producesCondition; private final RequestConditionHolder customConditionHolder; }
查看PatternsRequestCondition
public final class PatternsRequestCondition extends AbstractRequestCondition { public Set getPatterns() { return patterns; } private final Set patterns; private final UrlPathHelper pathHelper; private final PathMatcher pathMatcher; private final boolean useSuffixPatternMatch; private final boolean useTrailingSlashMatch; private final List fileExtensions; }
//HandlerMethod public class HandlerMethod { public HandlerMethod(Object bean, Method method) { this.bean = bean; beanFactory = null; this.method = method; bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); parameters = initMethodParameters(); } public transient HandlerMethod(Object bean, String methodName, Class parameterTypes[]) throws NoSuchMethodException { this.bean = bean; beanFactory = null; method = bean.getClass().getMethod(methodName, parameterTypes); bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); parameters = initMethodParameters(); } public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) { bean = beanName; this.beanFactory = beanFactory; this.method = method; bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); parameters = initMethodParameters(); } protected HandlerMethod(HandlerMethod handlerMethod) { bean = handlerMethod.bean; beanFactory = handlerMethod.beanFactory; method = handlerMethod.method; bridgedMethod = handlerMethod.bridgedMethod; parameters = handlerMethod.parameters; } private HandlerMethod(HandlerMethod handlerMethod, Object handler) { bean = handler; beanFactory = handlerMethod.beanFactory; method = handlerMethod.method; bridgedMethod = handlerMethod.bridgedMethod; parameters = handlerMethod.parameters; } private final Object bean; private final BeanFactory beanFactory; private final Method method; private final Method bridgedMethod; private final MethodParameter parameters[]; }
总结:
从以上分析,可以看出RequestMappingHandlerMapping,主要做的工作是将Contoller的带RequestMapping方法,添加到处理方法映射器和路径方法解决器中。
发表评论
-
Spring-RequestMappingHandlerAdapter初始化及请求处理
2016-09-22 11:50 10572看这篇文章之前,最好先看下面这篇,以便更好的理解handler ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3093浅谈Spring事务隔离级别:http://www.cnblo ... -
Spring的DefaultAnnotationHandlerMapping详解
2016-09-20 08:47 5838前面我们讲解过Dispatcher ... -
Spring-DispatcherServlet请求处理
2016-09-19 15:42 1683Spring-DispatcherServlet初始化详解:h ... -
Spring-DispatcherServlet初始化详解
2016-09-19 15:03 3688Spring-DispatcherServlet请求处理:ht ... -
Spring上下文加载监听器ContextLoaderListener--源码解析
2016-09-18 18:10 4654一般在web应用配置Spring上下文如下,那么Context ... -
JobDetailFactoryBean与MethodInvokingJobDetailFactoryBean源码分析
2016-09-13 16:07 4292Spring与Quartz集成详解:http://donald ... -
Spring与Quartz集成-源码分析
2016-09-13 11:50 2711在阅读以下文章之前,如果对Quartz任务调度不是很熟悉,请看 ... -
Spring与Quartz集成详解
2016-09-09 17:52 2816首先这个所有的依赖包就不需要多讲了,首先下载Quazrt发布包 ... -
Spring,ApplicationContextAware的作用
2016-08-24 17:38 7引用:http://blog.csdn.net/kaiwii/ ... -
Spring Interceptor
2016-05-31 17:12 569Spring Interceptor相关知识:http://h ... -
基于注解的Spring AOP
2016-05-31 16:05 921Spring AOP 基本概念:http://hotstron ... -
Spring的Task定时器
2016-05-31 10:34 7051.开启注解,定义扫描包 <mvc:annotation ...
相关推荐
### Spring RequestMappingHandlerMapping详解 #### 一、前言 `RequestMappingHandlerMapping`是Spring MVC框架中的核心组件之一,主要用于处理HTTP请求与控制器方法之间的映射关系。通过使用这一组件,开发者可以...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> <!-- 处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation....
### Spring MVC核心组件之HandlerMapping详解 #### 一、引言 在Java Web开发领域,Spring MVC框架因其灵活且强大的特性而备受青睐。它提供了一种简洁的方式来构建可维护、可扩展的应用程序。Spring MVC的核心组件之...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> ...
`RequestMappingHandlerMapping`是Spring MVC实现请求映射的关键部分,它不仅负责找到处理请求的控制器方法,还负责组装处理链,包括拦截器的配置,以确保整个请求处理流程的正确性和灵活性。理解这个组件的工作原理...
"详解获取Spring MVC中所有RequestMapping以及对应方法和参数" Spring MVC是一个基于模型-视图-控制器(MVC)模式的Web应用程序框架, RequestMapping是一个重要的注解,它可以将HTTP请求映射到控制器的方法上。在...
### Spring MVC框架详解 #### 一、Spring MVC框架概述 Spring MVC是Spring框架的一个模块,专为基于Web的应用程序提供了一种清晰、简洁的方式来构建Web应用程序。与传统的Servlet API编程方式相比,Spring MVC提供...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!-- 处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation....
**Spring MVC配置详解** Spring MVC 是 Spring 框架的一部分,专门用于构建 Web 应用程序。它提供了模型-视图-控制器(MVC)架构,使得开发人员能够有效地分离业务逻辑、数据处理和用户界面。Spring MVC 提供了丰富...
### Spring MVC 框架详解 #### 一、Spring MVC 概述 Spring MVC 是 Spring 框架中的一部分,主要用于构建基于 Java 的 Web 应用程序。它遵循 MVC(Model-View-Controller)设计模式,能够清晰地将业务逻辑、用户...
Spring MVC 提供了几种不同的 HandlerMapping 实现,如 `BeanNameUrlHandlerMapping`、`SimpleUrlHandlerMapping` 和 `RequestMappingHandlerMapping` 等。 2. **HandlerAdapter**:负责调用控制器的方法。每个控制...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> ...
**Spring MVC 实例详解** Spring MVC 是 Spring 框架的一部分,它是一个用于构建 Web 应用程序的 Model-View-Controller(MVC)架构。这个框架提供了处理 HTTP 请求、数据绑定、验证、视图渲染等多种功能,极大地...
**Spring MVC XML详解** Spring MVC 是 Spring 框架的一部分,专门用于构建Web应用程序。它提供了模型-视图-控制器(MVC)架构,帮助开发者有效地分离业务逻辑、数据处理和用户界面。在这个主题中,我们将深入探讨...
【Java配置详解——Spring与Ajax整合实践】 在Java开发领域,Spring框架以其强大的依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)能力,成为了企业级应用开发的首选。...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> ...
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> ``` 在上面的配置中,我们定义了一个名为myInterceptor的拦截器,并将其...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> ...
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> ...