首页 > 编程语言 >SpringMVC源码-创建ContentNegotiationManagerFactoryBean

SpringMVC源码-创建ContentNegotiationManagerFactoryBean

时间:2022-11-01 20:23:10浏览次数:41  
标签:SpringMVC strategy 源码 ContentNegotiationManagerFactoryBean new strategies null m

一、ContentNegotiationManagerFactoryBean的BeanDifinition及实现的接口

上图的属性说的是ContentNegotiationManagerFactoryBean对应的BeanDifinition中设置的属性,需要被注入bean中。右边表示实现的接口。

ContentNegotiationManagerFactoryBean实现了FactoryBean接口用于创建ContentNegotiationManager类型的bean实例。同时配置ContentNegotiationStrategy实例。

ContentNegotiationManager用于解析请求中的MediaType,及将MediaType解析成文件扩展名。

二、实例化ContentNegotiationManagerFactoryBean

在ContentNegotiationManagerFactoryBean.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)中:

BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}

createBeanInstance调用了ContentNegotiationManagerFactoryBean的默认构造方法实例化对象。

populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);

populateBean填充mediaTypes属性。initializeBean调用bean的init方法,即实现了InitializingBean接口的afterPropertiesSet方法。

ContentNegotiationManagerFactoryBean.afterPropertiesSet()

public void afterPropertiesSet() {
	build();
}

ContentNegotiationManagerFactoryBean.build()

	public ContentNegotiationManager build() {
	List<ContentNegotiationStrategy> strategies = new ArrayList<>();

	if (this.strategies != null) {
		strategies.addAll(this.strategies);
	}
	else {
		if (this.favorPathExtension) {
			PathExtensionContentNegotiationStrategy strategy;
			if (this.servletContext != null && !useRegisteredExtensionsOnly()) {
				strategy = new ServletPathExtensionContentNegotiationStrategy(this.servletContext, this.mediaTypes);
			}
			else {
				strategy = new PathExtensionContentNegotiationStrategy(this.mediaTypes);
			}
			strategy.setIgnoreUnknownExtensions(this.ignoreUnknownPathExtensions);
			if (this.useRegisteredExtensionsOnly != null) {
				strategy.setUseRegisteredExtensionsOnly(this.useRegisteredExtensionsOnly);
			}
			strategies.add(strategy);
		}
		if (this.favorParameter) {
			ParameterContentNegotiationStrategy strategy = new ParameterContentNegotiationStrategy(this.mediaTypes);
			strategy.setParameterName(this.parameterName);
			if (this.useRegisteredExtensionsOnly != null) {
				strategy.setUseRegisteredExtensionsOnly(this.useRegisteredExtensionsOnly);
			}
			else {
				strategy.setUseRegisteredExtensionsOnly(true);  // backwards compatibility
			}
			strategies.add(strategy);
		}
		if (!this.ignoreAcceptHeader) {
			strategies.add(new HeaderContentNegotiationStrategy());
		}
		if (this.defaultNegotiationStrategy != null) {
			strategies.add(this.defaultNegotiationStrategy);
		}
	}

	this.contentNegotiationManager = new ContentNegotiationManager(strategies);

	// Ensure media type mappings are available via ContentNegotiationManager#getMediaTypeMappings()
	// independent of path extension or parameter strategies.

	if (!CollectionUtils.isEmpty(this.mediaTypes) && !this.favorPathExtension && !this.favorParameter) {
		this.contentNegotiationManager.addFileExtensionResolvers(
				new MappingMediaTypeFileExtensionResolver(this.mediaTypes));
	}

	return this.contentNegotiationManager;
}

favorPathExtension表示将mediaTypes解析成文件扩展名。默认为false。ServletPathExtensionContentNegotiationStrategy使用ServletContext#getMimeType(String)解析成文件扩展名。PathExtensionContentNegotiationStrategy--解析请求用于查找媒体类型的键的路径。
favorParameter表示是否将查询参数解析成content type。默认为false。ParameterContentNegotiationStrategy将查询参数解析成content type的策略。
ignoreAcceptHeader表示是否忽略Accept请求头。HeaderContentNegotiationStrategy检查Accept请求头。
MappingMediaTypeFileExtensionResolver是MediaType到文件扩展名的解析器。

标签:SpringMVC,strategy,源码,ContentNegotiationManagerFactoryBean,new,strategies,null,m
From: https://www.cnblogs.com/shigongp/p/16848940.html

相关文章

  • SpringMVC-mvc context重载AbstractApplicationContext.refresh方法部分
    一、postProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)AbstractRefreshableWebApplicationContext.postProcessBeanFactory(ConfigurableListableBea......
  • 上传大文件解决方案源码
    ​ 前言:因自己负责的项目(jetty内嵌启动的SpringMvc)中需要实现文件上传,而自己对java文件上传这一块未接触过,且对Http协议较模糊,故这次采用渐进的方式来学习文件上传的......
  • 【lwip】07-链路层收发以太网数据帧源码分析
    目录前言7.1链路层概述7.2MAC地址的基本概念7.3以太网帧结构7.4以太网帧结构7.5以太网帧报文数据结构7.6发送以太网数据帧7.7接收以太网数据帧7.8虚拟局域网VLAN源......
  • vue源码分析-基础的数据代理检测
    简单回顾一下这个系列的前两节,前两节花了大量的篇幅介绍了Vue的选项合并,选项合并是Vue实例初始化的开始,Vue为开发者提供了丰富的选项配置,而每个选项都严格规定了合并的策......
  • vue源码分析-响应式系统(二)
    为了深入介绍响应式系统的内部实现原理,我们花了一整节的篇幅介绍了数据(包括data,computed,props)如何初始化成为响应式对象的过程。有了响应式数据对象的知识,上一节的后......
  • vue源码分析-响应式系统工作原理
    上一章,我们讲到了Vue初始化做的一些操作,那么我们这一章来讲一个Vue核心概念响应式系统。我们先来看一下官方对深入响应式系统的解释:当你把一个普通的JavaScript对象传......
  • 小白入门kafka-附源码
    现在消息队列的主流kafaka面试过程中经常被提到,所以进行了学习和总结现在分享给大家,如有疑问可以评论沟通。 基础API使用源码和spirngboot+kafka集成源码:https://files.......
  • 基于nodejs的预约上门维修服务系统设计与实现-计算机毕业设计源码+LW文档
    开发语言:nodejs框架:Express数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:VScode/HBuilderX浏览器:谷歌浏览器数据库脚本:DROPTABLEIFEXISTS​​config......
  • SpringMVC
    SpringMVCMVC:模型(dao,service) 视图(jsp) 控制器(servlet)前端 数据传输 实体类实体类:用户名,密码,生日,爱好,,,,前端:用户名,密码pojo:Uservo:UserVo假设:你的项目的......
  • 基于nodejs电影交流网站设计与实现-计算机毕业设计源码+LW文档
    摘 要网络的广泛应用给生活带来了十分的便利。所以把电影交流管理与现在网络相结合,利用nodejs技术建设电影交流网站,实现电影交流的信息化。则对于进一步提高电影交流管理......