动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

Spring MVC三大组件初始化

08-19 17:43 240浏览
举报 T字号
  • 大字
  • 中字
  • 小字

Spring MVC的三大组件HandlerMapping,HandlerAdapter和ViewResolve我们都不陌生,在之前的文章里我们熟悉了它们的功能和构造,本文我们来学习Spring MVC三大组件初始化

在我们分析Spring MVC组件HandlerMapping、HandlerAdapter、ViewResolve之前,我们先看一下我们的springMVC-conf.xml配置文件,mvc的配置文件中,我们配置了两行代码:

 

 

复制代码第二行代码主要是添加了默认的HandleMapping,ViewResolver,HandleAdapter。我们看annotation-driven的源码定义,根据spring自定义schema定义,我们找到如下代码,如图所示:

该文件就一行代码:

http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler

//MVC所有的标签解析器都定义在此

public class MvcNamespaceHandler extends NamespaceHandlerSupport {

@Override

public void init() {

registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());

registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());

registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());

registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());

registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());

registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());

registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());

registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());

registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());

registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());

registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());

registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());

registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());

}

}

那么通过分析AnnotationDrivenBeanDefinitionParser类,主要完成Spring MVC三大组件初始化装配工作:

1.初始化处理器映射器

private void initHandlerMappings(ApplicationContext context) {

this.handlerMappings = null;



    //这里detectAllHandlerMappings默认值为true,可以通过配置文件设置为false

if (this.detectAllHandlerMappings) {

    //从上下文(包含父上下文)中查找所有HandlerMapping实现类

Map matchingBeans =

BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);

if (!matchingBeans.isEmpty()) {

this.handlerMappings = new ArrayList<>(matchingBeans.values());

AnnotationAwareOrderComparator.sort(this.handlerMappings);

}

}

else {

try {

    //这里只取固定的bean

HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);

this.handlerMappings = Collections.singletonList(hm);

}

catch (NoSuchBeanDefinitionException ex) {



}

}



/***

  确保至少有一个HandlerMapping,如果没能找到,注册一个默认的

  默认规则在DispatcherServlet.properties中,这里也就是取BeanNameUrlHandlerMapping、RequestMappingHandlerMapping

***/

if (this.handlerMappings == null) {

this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);

}

}

2.初始化处理器适配器

private void initHandlerAdapters(ApplicationContext context) {

this.handlerAdapters = null;



if (this.detectAllHandlerAdapters) {

    //从上下文(包括父上下文)中查找所有HandlerAdapter实现类

Map matchingBeans =BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);

if (!matchingBeans.isEmpty()) {

this.handlerAdapters = new ArrayList<>(matchingBeans.values());

AnnotationAwareOrderComparator.sort(this.handlerAdapters);

}

}

else {

try {

    //这里取bean名字为handlerAdapter,类型为HandlerAdapter的处理器适配器

HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);

this.handlerAdapters = Collections.singletonList(ha);

}

catch (NoSuchBeanDefinitionException ex) {



}

}



/**

如果没找到,则从默认规则里取出指定的三个实现类:HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、RequestMappingHandlerAdapter

**/

if (this.handlerAdapters == null) {

this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);

}

}

3.初始化视图解析器

private void initViewResolvers(ApplicationContext context) {

this.viewResolvers = null;



if (this.detectAllViewResolvers) {

    //从上下文(包括父上下文)中查找所有ViewResolver实现类

Map matchingBeans =BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);

if (!matchingBeans.isEmpty()) {

this.viewResolvers = new ArrayList<>(matchingBeans.values());

AnnotationAwareOrderComparator.sort(this.viewResolvers);

}

}

else {

try {

ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);

this.viewResolvers = Collections.singletonList(vr);

}

catch (NoSuchBeanDefinitionException ex) {



}

}



/**

如果没找到,则从默认规则里取出指定的实现类:InternalResourceViewResolver

**/

if (this.viewResolvers == null) {

this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);

}

}

三大组件的初始化最后判断为NULL时都会调用getDefaultStrategies方法,也就是从DispatcherServlet.properties中取出指定默认值。

protected  List getDefaultStrategies(ApplicationContext context, Class strategyInterface) {

String key = strategyInterface.getName();

String value = defaultStrategies.getProperty(key);

if (value != null) {

String[] classNames = StringUtils.commaDelimitedListToStringArray(value);

List strategies = new ArrayList<>(classNames.length);

for (String className : classNames) {

try {

Class clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());

Object strategy = createDefaultStrategy(context, clazz);

strategies.add((T) strategy);

}

catch (ClassNotFoundException ex) {

throw new BeanInitializationException("Could not find DispatcherServlet's default strategy class [" + className +"] for interface [" + key + "]", ex);

}

catch (LinkageError err) {

throw new BeanInitializationException("Unresolvable class definition for DispatcherServlet's default strategy class [" +className + "] for interface [" + key + "]", err);

}

}

return strategies;

}

else {

return new LinkedList<>();

}

}

总的来说,Spring MVC三大组件初始化并不复杂,内容也不是很多,只要稍微用心,就不难掌握。当然,这也是在有一定的Spring MVC框架使用基础的前提下,如果你的基础不是很好的话,可以观看本站的Spring MVC视频教程学习Spring MVC框架的基础知识。

 

 

0人推荐
共同学习,写下你的评论
0条评论
十年
程序员十年

13篇文章贡献72369字

作者相关文章更多>

推荐相关文章更多>

DOM渲染的详细过程

QCode09-04 14:38

CSS水平和垂直居中技巧大梳理

Code大师09-04 14:50

mui的input框在IOS系统下无法聚焦或点击多次才能聚焦

不写代码你养我啊08-23 11:14

推荐的-视.频播放器以及在线客服

不写代码你养我啊09-17 18:02

谈谈java多线程的三大特性

要学习了06-18 18:13

发评论

举报

0/150

取消