96SEO 2026-02-20 10:13 0
DispatcherServlet委托如下一些特殊的bean来处理请求、并渲染正确的返回。

这些特殊的bean是Spring
MVC框架管理的bean、按照Spring框架的约定处理相关请求其实也就是DispatcherServilet的初始化过程。
DispatcherServlet委托如下一些特殊的bean来处理请求、并渲染正确的返回。
这些特殊的bean是Spring
MVC框架管理的bean、按照Spring框架的约定处理相关请求一般情况下是框架内置的我们当然也可以定制或扩展他们的功能。
HandlerMapping根据一定的规则把请求映射到对应的HandlerMapping去处理HandlerMapping可以包含一系列拦截器进行前置或后置处理。
框架默认提供了RequestMappingHandlerMapping处理RequestMapping注解方法的和SimpleUrlHandlerMapping两个HandlerMapping。
HandlerAdapterHandlerMapping匹配到请求之后调用HandlerAdapter具体处理请求。
HandlerExceptionResolver发生异常后的异常处理器。
ViewResolver处理返回LocaleResolver,
LocaleContextResolver本地化处理器ThemeResolverTheme渲染处理器MultipartResolverMultipart处理器文件上传下载的处理。
FlashMapManager跨请求存储和获取“input”和“output”的处理器
DispatcherServlet初始化过程中会根据WebApplicationContext的配置xml或注解方式前面两篇文章分析过完成上述特殊bean的初始化如果DispatcherServlet在WebApplicationContext中没有发现相应的配置则采用DispatcherServlet.properties文件中的默认配置完成初始化。
DispatcherServlet.properties文件在Spring
MVC框架是通过DispatcherServlet的init方法完成上述各特殊bean的初始化的下面我们要详细分析一下具体的初始化过程。
通过注解方式、或通过xml方式初始化DispatcherServlet的具体方法前面两篇文章已经做过分析此处不在赘述。
众所周知Servlet容器比如Tomcat会通过调用Servlet的init方法完成Servlet的初始化。
我们接下来看一下DispatcherServlet的初始化过程也就是DispatcherServlet的init方法。
ServletConfigPropertyValues(getServletConfig(),
PropertyAccessorFactory.forBeanPropertyAccess(this);ResourceLoader
ServletContextResourceLoader(getServletContext());bw.registerCustomEditor(Resource.class,
getEnvironment()));initBeanWrapper(bw);bw.setPropertyValues(pvs,
like.initServletBean();}上面的代码是对当前Servlet属性的处理与我们的目标无关初始化逻辑在最下面的方法initServletBean中在他的子类也是DispatcherServlet的直接父类FrameworkServlet中
initWebApplicationContext();initFrameworkServlet();}catch
ex;}该方法中有很多打印log的代码忽略掉剩下的就是两个方法的调用一个是创建webApplicationContext的一个是initFrameworkServlet这个initFrameworkServlet是空方法所以DispatcherServlet的初始化逻辑关键就在这个initWebApplicationContext()方法中。
initWebApplicationContext方法很长我们分段分析一下。
WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext
null;...首先获取当前ServletContext的RootContext有关RootContext参见前面的文章
ConfigurableWebApplicationContext)
{ConfigurableWebApplicationContext
(ConfigurableWebApplicationContext)
parentcwac.setParent(rootContext);}configureAndRefreshWebApplicationContext(cwac);}}}判断如果DispatcherServlet对象创建的时候如果在构造方法中已经初始化过WebApplicationContext了那么就使用该WebApplicationContext设置上面获取到的RootContext为当前WebApplicationContext的父容器。
并且判断该Context是否已经刷新过如果没有刷新过的话调用configureAndRefreshWebApplicationContext方法配置并刷新该Context。
基于注解配置中我们分析过DispatcherServlet的创建过程确实在创建的时候就通过构造函数的参数传过来已经创建好的ServletContext了
registerDispatcherServlet(ServletContext
getServletName();Assert.hasLength(servletName,
createServletApplicationContext();Assert.notNull(servletAppContext,
createServletApplicationContext()
createDispatcherServlet(servletAppContext);Assert.notNull(dispatcherServlet,
createDispatcherServlet(WebApplicationContext)
null);dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());...省略代码所以如果是通过注解方式配置的话会通过createServletApplicationContext()方法创建ServletContext
createServletApplicationContext()
{AnnotationConfigWebApplicationContext
AnnotationConfigWebApplicationContext();Class?[]
(!ObjectUtils.isEmpty(configClasses))
{context.register(configClasses);}return
context;}最终创建的ServletContext是AnnotationConfigWebApplicationContext。
否则如果不是通过注解、而是通过xml配置也就是说DispactherServlet创建的时候并没有ServletContext会走到下面的逻辑中
findWebApplicationContext();}if
createWebApplicationContext(rootContext);}如果wac为空DispatcherServlet创建的时候没有设置那么就判断容器中是否已经注册进来了如果已经注册了的话那么Spring
framework就会认为其父容器已经设置过了也做过初始化以及refresh了直接拿过来用就OK。
我们的应用如果不主动注册的话就不会有注册进来的Context所以这段代码就跑不到。
然后看下面的代码如果没有发现就调用createWebApplicationContext创建createWebApplicationContext方法在创建WebApplicationContext之后也会设置其父容器为RootContext之后也会调用configureAndRefreshWebApplicationContext配置和刷新容器走到和上面第一步通过注解方式配置DispatcherServlet创建的时候已经通过构造器设置了一个Context一致的逻辑中了。
createWebApplicationContext(Nullable
(!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass))
ApplicationContextException(Fatal
ConfigurableWebApplicationContext);}ConfigurableWebApplicationContext
(ConfigurableWebApplicationContext)
BeanUtils.instantiateClass(contextClass);wac.setEnvironment(getEnvironment());wac.setParent(parent);String
{wac.setConfigLocation(configLocation);}configureAndRefreshWebApplicationContext(wac);return
wac;}首先调用getContextClass()方法获取contextClass
XmlWebApplicationContext.class;private
this.contextClass;}可以看到如果不是通过注解方式启动、而是通过xml配置方式启动的话创建的ServletContext应该就是这个XmlWebApplicationContext。
创建ServletContext之后与xml配置方式一样设置父容器然后调用configureAndRefreshWebApplicationContext方法配置及刷新容器。
接下来我们看configureAndRefreshWebApplicationContext方法。
configureAndRefreshWebApplicationContext
目前为止我们前面的猜测通过DispatcherServlet的init方法初始化各个特殊bean。
尚未的到证实
在DispatcherServlet的init方法中我们尚未看到相关的初始化代码。
不过代码还没分析完还有一个configureAndRefreshWebApplicationContext我们继续分析。
configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext
(ObjectUtils.identityToString(wac).equals(wac.getId()))
{wac.setId(this.contextId);}else
id...wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX
ObjectUtils.getDisplayString(getServletContext().getContextPath())
getServletName());}}为WebApplicationContext设置Id无关紧要继续看下面的代码
wac.setServletContext(getServletContext());wac.setServletConfig(getServletConfig());wac.setNamespace(getNamespace());wac.addApplicationListener(new
设置ServletContext、ServletConfig、以及namespace之后新增了一个监听器ContextRefreshListener()。
#refreshConfigurableEnvironment
env).initPropertySources(getServletContext(),
getServletConfig());}postProcessWebApplicationContext(wac);applyInitializers(wac);wac.refresh();}设置环境变量以及获取初始化参数最后调用WebApplicationContext的refresh方法。
依然没有看到DispatcherServlet对特殊bean的初始化而且现在的代码逻辑是转到了ApplicationContext中是Spring
Framework中来了。
所以说Spring全家桶不管是Spring
ApplicationContext的refresh方法我们很熟悉了是Spring
Framework的关键方法在AbstractApplicationContext类中实现该方法最后会调用到finishRefresh()方法
finishRefresh()方法最后会发布ContextRefreshedEvent事件。
没错前面代码分析过程中我们确实是在WebApplicationContext容器中注册了一个针对该事件的监听器ContextRefreshListener
ApplicationListenerContextRefreshedEvent
onApplicationEvent(ContextRefreshedEvent
{FrameworkServlet.this.onApplicationEvent(event);}}该监听器是定义在FrameworkServlet中的一个内部类其onApplicationEvent方法会调用到FrameworkServlet的onApplicationEvent方法这样通过监听机制代码逻辑就再次转回到了DispatcherServlet确切说是他的父类FrameworkServlet中来了
onApplicationEvent(ContextRefreshedEvent
{onRefresh(event.getApplicationContext());}}最终会调用到DispatcherServlet中来
{initStrategies(context);}查看DispatcherServlet代码我们会发现这个initStrategies正式我们要找的方法方法参数Context是通过事件传递过来的因此DispatcherSerlet在进行初始化的时候可以持有ApplicationContext对象然后随心所欲地完成Spring
篇幅原因关于DispatcherServlet的具体初始化过程我们后面分析。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback