Spring源码学习25


1.SpringMVC十大核心对象

接口使用场景实现类参考博客
MultipartResolver用于解析文件上传CommonsMultipartResolver 
StandardServletMultipartResolver 
LocaleResolver用于国际化CookieLocaleResolver 
FixedLocaleResolver 
AcceptHeaderLocaleResolver 
SessionLocaleResolver 
ThemeResolver用户控制页面主题风格FixedThemeResolver 
SessionThemeResolver 
CookieThemeResolver 
HandlerMapping用于为一个请求找到处理类或者处理方法BeanNameUrlHandlerMappinghttps://blog.youkuaiyun.com/qq_23536449/article/details/99944430
SimpleUrlHandlerMappinghttps://blog.youkuaiyun.com/qq_23536449/article/details/99944430
RequestMappingHandlerMappinghttps://blog.youkuaiyun.com/qq_23536449/article/details/99944430
HandlerAdapter适配请求处理对象,调用处理器的方法处理请求SimpleMappingExceptionResolver 
RequestMappingHandlerAdapter 
SimpleControllerHandlerAdapter 
HandlerExceptionResolver异常解析处理器,比如给异常返回状态码、返回json文件、返回到某个错误页面ExceptionHandlerExceptionResolver 
DefaultHandlerExceptionResolver 
ResponseStatusExceptionResolver 
RequestToViewNameTranslator在返回view为空时,它能够根据request请求获得viewNameDefaultRequestToViewNameTranslator 
ViewResolver视图解析器,把逻辑视图名称解析为View对象InternalResourceViewResolver 
UrlBasedViewResolver 
BeanNameViewResolver 
ViewResolverComposite 
XmlViewResolver 
FlashMapManager重定向请求传参用获取上一个request的参数信息SessionFlashMapManager 
View视图展示,比如jsp、html、excel、pdf都是视图InternalResourceView 
JstlView 
AbstractPdfView 
AbstractXlsView 

 2.核心对象的初始化

/**
     * 初始化此servlet使用的策略对象。
     * <p>可以在子类中重写以初始化其他策略对象。
     */
    protected void initStrategies(ApplicationContext context) {
        //用于解析文件上传
        initMultipartResolver(context);
        //用于配置国际化
        initLocaleResolver(context);
        //用于控制主题页面的风格
        initThemeResolver(context);
        //用于为一个请求找到处理类或者处理方法
        initHandlerMappings(context);
        //适配请求处理对象,调用处理器的方法处理请求
        initHandlerAdapters(context);
        //异常解析处理器,比如给异常返回状态码、返回json文件、返回到某个错误页面
        initHandlerExceptionResolvers(context);
        //在返回view为空时,它能够根据request请求获得viewName
        initRequestToViewNameTranslator(context);
        //视图解析器,把逻辑视图名称解析为View对象
        initViewResolvers(context);
        //重定向请求传参用获取上一个request的参数信息
        initFlashMapManager(context);
    }

a.初始化MultipartResolver对象

 /**
     * 初始化此类使用的MultipartResolver
     * <p>如果没有在BeanFactory中为此命名空间定义具有给定名称的bean,则不提供Multipart的处理。
     */
    private void initMultipartResolver(ApplicationContext context) {
        try {
            this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");
            }
        } catch (NoSuchBeanDefinitionException ex) {
            // Default is no multipart resolver.
            this.multipartResolver = null;
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME +
                        "': no multipart request handling provided");
            }
        }
    }

b.初始化LocaleResolver

/**
     * 初始化此类使用的LocaleResolver。
     * <p>如果在此命名空间的BeanFactory中没有使用给定名称定义bean,则默认为AcceptHeaderLocaleResolver。
     */
    private void initLocaleResolver(ApplicationContext context) {
        try {
            this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using LocaleResolver [" + this.localeResolver + "]");
            }
        } catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default.
            // 创建默认的哎嘿嘿
            this.localeResolver = getDefaultStrategy(context, LocaleResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME +
                        "': using default [" + this.localeResolver + "]");
            }
        }
    }

c.初始化ThemeResolver

/**
     * 初始化此类使用的ThemeResolver。
     * <p>如果在此命名空间的BeanFactory中没有使用给定名称定义bean,则默认为FixedThemeResolver。
     */
    private void initThemeResolver(ApplicationContext context) {
        try {
            this.themeResolver = context.getBean(THEME_RESOLVER_BEAN_NAME, ThemeResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using ThemeResolver [" + this.themeResolver + "]");
            }
        } catch (NoSuchBeanDefinitionException ex) {
            // 从
            this.themeResolver = getDefaultStrategy(context, ThemeResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ThemeResolver with name '" + THEME_RESOLVER_BEAN_NAME +
                        "': using default [" + this.themeResolver + "]");
            }
        }
    }

d.初始化HandlerMappings

/**
     * 初始化此类使用的HandlerMappings。
     * <p>如果没有在BeanFactory中为此命名空间定义HandlerMapping bean,我们默认为BeanNameUrlHandlerMapping。
     */
    private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;

        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<HandlerMapping>(matchingBeans.values());
                // We keep HandlerMappings in sorted order.
                AnnotationAwareOrderComparator.sort(this.handlerMappings);
            }
        } else {
            try {
                HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
                this.handlerMappings = Collections.singletonList(hm);
            } catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default HandlerMapping later.
            }
        }

        // Ensure we have at least one HandlerMapping, by registering
        // a default HandlerMapping if no other mappings are found.
        if (this.handlerMappings == null) {
            this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
            if (logger.isDebugEnabled()) {
                logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
            }
        }
    }

e.初始化HandlerAdapters

 /**
     * Initialize the HandlerAdapters used by this class.
     * <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
     * we default to SimpleControllerHandlerAdapter.
     */
    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<HandlerAdapter>(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);
            } catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default HandlerAdapter later.
            }
        }

        // Ensure we have at least some HandlerAdapters, by registering
        // default HandlerAdapters if no other adapters are found.
        if (this.handlerAdapters == null) {
            this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
            if (logger.isDebugEnabled()) {
                logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
            }
        }
    }

f.初始化HandlerExceptionResolvers

/**
     * 初始化此类使用的HandlerExceptionResolver。
     * <p>如果在此命名空间的BeanFactory中没有使用给定名称定义bean,则默认情况下不会出现异常解析程序。
     */
    private void initHandlerExceptionResolvers(ApplicationContext context) {
        this.handlerExceptionResolvers = null;

        if (this.detectAllHandlerExceptionResolvers) {
            // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
            Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
                    .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());
                // We keep HandlerExceptionResolvers in sorted order.
                AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
            }
        } else {
            try {
                HandlerExceptionResolver her =
                        context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
                this.handlerExceptionResolvers = Collections.singletonList(her);
            } catch (NoSuchBeanDefinitionException ex) {
                // Ignore, no HandlerExceptionResolver is fine too.
            }
        }

        // Ensure we have at least some HandlerExceptionResolvers, by registering
        // default HandlerExceptionResolvers if no other resolvers are found.
        if (this.handlerExceptionResolvers == null) {
            this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("No HandlerExceptionResolvers found in servlet '" + getServletName() + "': using default");
            }
        }
    }

g.初始化RequestToViewNameTranslator对象

/**
     * 初始化此servlet实例使用的RequestToViewNameTranslator。
     * <p>如果未配置任何实现,则默认为DefaultRequestToViewNameTranslator。
     */
    private void initRequestToViewNameTranslator(ApplicationContext context) {
        try {
            this.viewNameTranslator =
                    context.getBean(REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME, RequestToViewNameTranslator.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using RequestToViewNameTranslator [" + this.viewNameTranslator + "]");
            }
        } catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default.
            this.viewNameTranslator = getDefaultStrategy(context, RequestToViewNameTranslator.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate RequestToViewNameTranslator with name '" +
                        REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME + "': using default [" + this.viewNameTranslator +
                        "]");
            }
        }
    }

h.初始化ViewResolvers

 /**
     * 初始化此类使用的ViewResolvers。
     * <p>如果没有为此命名空间的BeanFactory定义ViewResolver bean,我们默认为InternalResourceViewResolver。
     */
    private void initViewResolvers(ApplicationContext context) {
        this.viewResolvers = null;

        if (this.detectAllViewResolvers) {
            // Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
            Map<String, ViewResolver> matchingBeans =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values());
                // We keep ViewResolvers in sorted order.
                AnnotationAwareOrderComparator.sort(this.viewResolvers);
            }
        } else {
            try {
                ViewResolver vr = context.getBean(VIEW_RESOLVER_BEAN_NAME, ViewResolver.class);
                this.viewResolvers = Collections.singletonList(vr);
            } catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default ViewResolver later.
            }
        }

        // Ensure we have at least one ViewResolver, by registering
        // a default ViewResolver if no other resolvers are found.
        if (this.viewResolvers == null) {
            this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
            if (logger.isDebugEnabled()) {
                logger.debug("No ViewResolvers found in servlet '" + getServletName() + "': using default");
            }
        }
    }

i.初始化FlashMapManager对象

/**
     * 初始化此servlet实例使用的{@link FlashMapManager}。
     * <p>如果没有配置任何实现,那么我们默认为{@code org.springframework.web.servlet.support.SessionFlashMapManager}。
     */
    private void initFlashMapManager(ApplicationContext context) {
        try {
            this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using FlashMapManager [" + this.flashMapManager + "]");
            }
        } catch (NoSuchBeanDefinitionException ex) {
            // We need to use the default.
            this.flashMapManager = getDefaultStrategy(context, FlashMapManager.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate FlashMapManager with name '" +
                        FLASH_MAP_MANAGER_BEAN_NAME + "': using default [" + this.flashMapManager + "]");
            }
        }
    }

3.SpringMVC默认给DispatcherSerlvet的九大对象提供的默认值通过如下方法获取

/**
 * 返回给定策略接口的默认策略对象。
 * <p>默认实现委托给{@link #getDefaultStrategies},期望列表中有一个对象。
 *
 * @param context           the current WebApplicationContext
 * @param strategyInterface the strategy interface
 * @return the corresponding strategy object
 * @see #getDefaultStrategies
 */
protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) {
    List<T> strategies = getDefaultStrategies(context, strategyInterface);
    if (strategies.size() != 1) {
        throw new BeanInitializationException(
                "DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]");
    }
    return strategies.get(0);
}

 protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
        //class 名称
        String key = strategyInterface.getName();
        //从DispatcherServlet.properties配置文件寻找className对应的类
        String value = defaultStrategies.getProperty(key);
        if (value != null) {
            //按逗号切分
            String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
            List<T> strategies = new ArrayList<T>(classNames.length);
            for (String className : classNames) {
                try {
                    //加载Class对象
                    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(
                            "Error loading DispatcherServlet's default strategy class [" + className +
                                    "] for interface [" + key + "]: problem with class file or dependent class", err);
                }
            }
            return strategies;
        } else {
            return new LinkedList<T>();
        }
    }

可以看到都是从defaultStrategies中获取的,我们在DispatcherServlet中找到该属性;并且找到该属性的初始化方法

private static final Properties defaultStrategies;

    static {
        // Load default strategy implementations from properties file.
        // This is currently strictly internal and not meant to be customized
        // by application developers.
        try {
            ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
            defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
        } catch (IOException ex) {
            throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
        }
    }

上面方法加载读取DispatcherServlet.properties文件:

# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
   org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
   org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
   org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter

org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
   org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
   org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值