spring源码---mvc:九大组件

一,九大组件

1.handlerMapping

    用来查找handler的,也就是处理器,对应的就是标签@RequestMapping。也就是说handler,可以是类,也可以是方法.

2.handlerAdapter

    我们最原始的servlet处理方式可以知道,当一个请求到达的时候,是封装成request发送到servlet的doService(HttpServletRequest,HttpServletResponse)形式的,所以,要从传统的servlet模式转到spring mvc,这里就需要一个适配器,将对应的url,映射到对应的handler上面

3.handlerExceptionResolver

    从名字上看,这个是处理handler异常的组件,此组件的作用是根据异常设置ModelAndView,之后交给渲染方法进行渲染,渲染方法将ModelAndView渲染成页面,返回给客户端。

4.ViewResolver

    视图解析器,功能是将string类型的视图名解析为View类型的视图,只有一个resolveViewName()方法。View用来渲染页面,也就是将程序返回的参数和数据填入模板中。

5.RequestToViewNameTranslator

    作用是从请求中获取ViewName,因为ViewResolver根据ViewName查找View,如果Handler处理完之后,没有设置View,也没有ViewName,这个时候就需要这个组件中查找ViewName。

6.LocaleResolver

    ViewResolver组件的resolveViewName()方法需要两个参数,一个是ViewName,一个就是Locale,Locale的获得就是该组件需要提供的,它从请求中解析出Locale,表示一个区域。中国locale就是zh-CN。

7.ThemeResolver

    解析主题,主题就是样式,图片以及他们所形成的显示效果的集合,spring mvc主题对应一个properties文件,里面存放着当前主题相关的所有资源。

8.MultipartResolver

    用于处理上传请求,通过将普通的请求包装成MultipartHttpServletRequest来实现,它可以通过getFIle()直接获取文件。简单来说就是封装请求,使其有文件上传的功能

9.FlashMapManager

    从名字可以知道,FlashMap的管理者,FlashMap用于重定向时的参数传递,

二,源码

继续回到DIspatcher类中的InitStrategies()方法:

1.initMultiparResolver()

  多文件上传的组件,

private void initMultipartResolver(ApplicationContext context) {
   try {
      //从容器中 获取bean 注意这些常量全是 bean的名字,他们在context初始化也就是Onfresh()方法的时候,已经把对应的Bean放入了容器中
      this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
     .....
}

我们看一下这些常量字段:

    很明显,这下面9个字段,正好对应9个组件,同时这9个字符串作为bean的名字,自然有对象的class对象,他们的具体实现保存在了一个Dispatcher.properties文件中。他们都会在spring mvc容器刷新的时候进行实例化,存放到容器中。

public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";

    第一个组件初始化比较简单,就是从容器中获取到对象的bean,然后注入到Servlet中,等待后面处理请求的时候进行调用。

2.initLocalResolver()

    初始化本地语言环境,它的操作和上面的多文件上传组件相同

private void initLocaleResolver(ApplicationContext context) {
   try {
      this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
     ...
}

3.initThemeResolver()

    同样是getBean()操作

private void initThemeResolver(ApplicationContext context) {
   try {
      this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
    ...
}

4.initHandlerMapping()

    处理器很重要,所以它的初始化也稍显不同,注意看下面的英文注解

private void initHandlerMappings(ApplicationContext context) {
   this.handlerMappings = null;
   //默认为true,即默认从所有的ioc容器中获取handlerMapping
   if (this.detectAllHandlerMappings) {
      // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
      Map<String, HandlerMapping> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
      if (!matchingBeans.isEmpty()) {
         this.handlerMappings = new ArrayList<>(matchingBeans.values());
         // We keep HandlerMappings in sorted order.
         AnnotationAwareOrderComparator.sort(this.handlerMappings);
      }
   }
   else { //否者从当前的Ioc容器中通过 getBean()获取所有bean名称为"handlerMapping"的handlerMapping
      try {
         HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
     ....
   }
   //如果没有handlerMapping,则从配置文件中获取
   if (this.handlerMappings == null) {
      this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
   }
}

    英文注解的含义比较清楚,首先从applicationContext中找到所以的hanlderMapping实现类,然后保存到Map中,如果不为空,则把map转成ArrayList保存,抛掉HandlerMapping的名字,如果HandlerMapping为空,那么就需要从web.xml中获取配置的类,

protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
   String key = strategyInterface.getName();
   String value = defaultStrategies.getProperty(key); //从web.xml中获取
   if (value != null) {
      String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
      List<T> 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);
         }   ...
      }
      return strategies;
   }
   else {
      return new LinkedList<>();
   }
}

5.initHandlerAdapters()

    初始化handler适配器,它的初始化模式和HandlerMapping完全一样,

private void initHandlerAdapters(ApplicationContext context) {
   this.handlerAdapters = null;

   if (this.detectAllHandlerAdapters) {
      // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
      Map<String, HandlerAdapter> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
      if (!matchingBeans.isEmpty()) {
         this.handlerAdapters = new ArrayList<>(matchingBeans.values());
         // We keep HandlerAdapters in sorted order.
         AnnotationAwareOrderComparator.sort(this.handlerAdapters);
      }
   }
   else {
      try {
         HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
         this.handlerAdapters = Collections.singletonList(ha);
     ...
   }

   if (this.handlerAdapters == null) {
      this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
     ...
   }
}

后面的组件初始化内容也差不多,这里就不展开叙述了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值