浏览 5849 次
锁定老帖子 主题:spring mvc请求映射关系处理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2012-01-04
protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); //初始化处理器映射关系,即用户请求与程序处理的对应关系 initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); } //initHandlerMappings默认会先探测ApplicationContext对象中已经设定好的任何HandlerMapping对象,如果有就使用定义好的,如果没有,调用方法getDefaultStrategies,使用默认配置,DisptatchServlet.properties文件中默认的org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping两个HandlerMapping对象。 2:看下DefaultAnnotationHandlerMapping类层次关系,BeanNameUrlHandlerMapping类层次是一样的 //类层次,凑合看 DefaultAnnotationHandlerMapping AbstractDetectingUrlHandlerMapping AbstractUrlHandlerMapping AbstractHandlerMapping extends WebApplicationObjectSupport implements HandlerMapping, Ordered //这里继承了WebApplicationObjectSupport对象,关于这个对象:Convenient superclass for application objects running in a WebApplicationContext. WebApplicationObjectSupport extends ApplicationObjectSupport implements ServletContextAware implements ApplicationContextAware 3:抽象类ApplicationObjectSupport实现了ApplicationContextAware,spring容器的后置处理器会调用setApplicationContext方法,执行顺序: //ApplicationObjectSupport中的setApplicationContext方法执行 public final void setApplicationContext(ApplicationContext context) throws BeansException { if (context == null && !isContextRequired()) { // Reset internal context state. this.applicationContext = null; this.messageSourceAccessor = null; } else if (this.applicationContext == null) { // Initialize with passed-in context. if (!requiredContextClass().isInstance(context)) { throw new ApplicationContextException( "Invalid application context: needs to be of type [" + requiredContextClass().getName() + "]"); } this.applicationContext = context; this.messageSourceAccessor = new MessageSourceAccessor(context); //这里会先执行子类WebApplicationObjectSupport的initApplicationContext方法,然后到ApplicationObjectSupport自己的init方法,ApplicationObjectSupport本身的该方法没有任何处理,只是调用了一个空的方法initApplicationContext(),这个无参的重载方法被当作一个钩子供子类方法来实现。 initApplicationContext(context); } else { // Ignore reinitialization if same context passed in. if (this.applicationContext != context) { throw new ApplicationContextException( "Cannot reinitialize with different application context: current one is [" + this.applicationContext + "], passed-in one is [" + context + "]"); } } } 4:initApplicationContext()执行,spring默认的两个处理器映射类都继承自AbstractDetectingUrlHandlerMapping抽象类,而且类初始化将被执行的initApplicationContext方法也在这个类得到了实现 //AbstractDetectingUrlHandlerMapping中的initApplicationContext方法 public void initApplicationContext() throws ApplicationContextException { //先执行超类的initApplicationContext方法,这个超类的方法完成的任务就是对定义好的拦截器改装并放入到adaptedInterceptors数组中供以后使用 super.initApplicationContext(); //请求与处理器映射的关键方法 detectHandlers(); } 5:detectHandlers()执行 protected void detectHandlers() throws BeansException { if (logger.isDebugEnabled()) { logger.debug("Looking for URL mappings in application context: " + getApplicationContext()); } //默认会取得上下文中的所有的对象的beanname。 String[] beanNames = (this.detectHandlersInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); // Take any bean name that we can determine URLs for. for (int i = 0; i < beanNames.length; i++) { String beanName = beanNames[i]; //abstract方法,在子类中实现,即找到符合要求的映射url String[] urls = determineUrlsForHandler(beanName); if (!ObjectUtils.isEmpty(urls)) { // URL paths found: Let's consider it a handler. //注册处理器,即添加一些映射关系到handlerMap中,一个LinkedHashMap registerHandler(urls, beanName); } else { if (logger.isDebugEnabled()) { logger.debug("Rejected bean name '" + beanNames[i] + "': no URL paths identified"); } } } } 6:determineUrlsForHandler方法执行,DefaultAnnotationHandlerMapping为例子 不贴了,主要就是挨个对象查看,DefaultAnnotationHandlerMapping类就是查看定义的RequestMapping注解,然后把符合要求的urls返回。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-01-11
乱糟糟的,随便贴过来的吧
|
|
返回顶楼 | |
发表时间:2012-01-12
jyjava 写道 乱糟糟的,随便贴过来的吧
晕,我看着原码一点一点敲的啊。 可能组织的不好吧。 |
|
返回顶楼 | |
发表时间:2012-01-17
再整理整理就 更好了
|
|
返回顶楼 | |