SpringMVC源码-mvc:annotation-driven解析

mvc namespace的处理器由webmvc项目下Resources/META-INF/spring.handlers文件:

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

决定。

MvcNamespaceHandler

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());
}

}

annotation-driven标签由AnnotationDrivenBeanDefinitionParser解析。

AnnotationDrivenBeanDefinitionParser

static {
	ClassLoader classLoader = AnnotationDrivenBeanDefinitionParser.class.getClassLoader();
	javaxValidationPresent = ClassUtils.isPresent("javax.validation.Validator", classLoader); // 类路径是否存在Validator校验
	romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", classLoader); // 类路径是否存在WireFeed
	jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader); // 类路径是否存在Binder
	jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
					ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); // 类路径是否存在jackson 序列化类ObjectMapper
	jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); //类路径是否存在XmlMapper-jackson 处理xml
	jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);  //类路径是否存在SmileFactory-处理二进制类似JSON数据
	jackson2CborPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory", classLoader); // 类路径是否存在CBORFactory-解析CBOR数据格式
	gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader); // 类路径是否存在Gson序列化
}

AnnotationDrivenBeanDefinitionParser.parse(Element element, ParserContext context)

public BeanDefinition parse(Element element, ParserContext context) {
	Object source = context.extractSource(element);
	XmlReaderContext readerContext = context.getReaderContext();

	CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
	context.pushContainingComponent(compDefinition);

	RuntimeBeanReference contentNegotiationManager = getContentNegotiationManager(element, source, context);

	RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
	handlerMappingDef.setSource(source);
	handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	handlerMappingDef.getPropertyValues().add("order", 0);
	handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);

	if (element.hasAttribute("enable-matrix-variables")) {
		boolean enableMatrixVariables = Boolean.parseBoolean(element.getAttribute("enable-matrix-variables"));
		handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
	}

	configurePathMatchingProperties(handlerMappingDef, element, context);
	readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);

	RuntimeBeanReference corsRef = MvcNamespaceUtils.registerCorsConfigurations(null, context, source);
	handlerMappingDef.getPropertyValues().add("corsConfigurations", corsRef);

	RuntimeBeanReference conversionService = getConversionService(element, source, context);
	RuntimeBeanReference validator = getValidator(element, source, context);
	RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);

	RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
	bindingDef.setSource(source);
	bindingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	bindingDef.getPropertyValues().add("conversionService", conversionService);
	bindingDef.getPropertyValues().add("validator", validator);
	bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);

	ManagedList<?> messageConverters = getMessageConverters(element, source, context);
	ManagedList<?> argumentResolvers = getArgumentResolvers(element, context);
	ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context);
	String asyncTimeout = getAsyncTimeout(element);
	RuntimeBeanReference asyncExecutor = getAsyncExecutor(element);
	ManagedList<?> callableInterceptors = getInterceptors(element, source, context, "callable-interceptors");
	ManagedList<?> deferredResultInterceptors = getInterceptors(element, source, context, "deferred-result-interceptors");

	RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
	handlerAdapterDef.setSource(source);
	handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
	handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
	handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
	addRequestBodyAdvice(handlerAdapterDef);
	addResponseBodyAdvice(handlerAdapterDef);

	if (element.hasAttribute("ignore-default-model-on-redirect")) {
		Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect"));
		handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
	}
	if (argumentResolvers != null) {
		handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
	}
	if (returnValueHandlers != null) {
		handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
	}
	if (asyncTimeout != null) {
		handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout);
	}
	if (asyncExecutor != null) {
		handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
	}

	handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors);
	handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors);
	readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);

	RootBeanDefinition uriContributorDef =
			new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class);
	uriContributorDef.setSource(source);
	uriContributorDef.getPropertyValues().addPropertyValue("handlerAdapter", handlerAdapterDef);
	uriContributorDef.getPropertyValues().addPropertyValue("conversionService", conversionService);
	String uriContributorName = MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME;
	readerContext.getRegistry().registerBeanDefinition(uriContributorName, uriContributorDef);

	RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
	csInterceptorDef.setSource(source);
	csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
	RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
	mappedInterceptorDef.setSource(source);
	mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null);
	mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
	String mappedInterceptorName = readerContext.registerWithGeneratedName(mappedInterceptorDef);

	RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
	methodExceptionResolver.setSource(source);
	methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	methodExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
	methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
	methodExceptionResolver.getPropertyValues().add("order", 0);
	addResponseBodyAdvice(methodExceptionResolver);
	if (argumentResolvers != null) {
		methodExceptionResolver.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
	}
	if (returnValueHandlers != null) {
		methodExceptionResolver.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
	}
	String methodExResolverName = readerContext.registerWithGeneratedName(methodExceptionResolver);

	RootBeanDefinition statusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
	statusExceptionResolver.setSource(source);
	statusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	statusExceptionResolver.getPropertyValues().add("order", 1);
	String statusExResolverName = readerContext.registerWithGeneratedName(statusExceptionResolver);

	RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
	defaultExceptionResolver.setSource(source);
	defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	defaultExceptionResolver.getPropertyValues().add("order", 2);
	String defaultExResolverName = readerContext.registerWithGeneratedName(defaultExceptionResolver);

	context.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
	context.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
	context.registerComponent(new BeanComponentDefinition(uriContributorDef, uriContributorName));
	context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName));
	context.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExResolverName));
	context.registerComponent(new BeanComponentDefinition(statusExceptionResolver, statusExResolverName));
	context.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExResolverName));

	// Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"
	MvcNamespaceUtils.registerDefaultComponents(context, source);

	context.popAndRegisterContainingComponent();

	return null;
}

1、调用getContentNegotiationManager创建ContentNegotiationManagerFactoryBean类型的BeanDefinition
2、创建RequestMappingHandlerMapping类型的RootBeanDefinition
3、为RequestMappingHandlerMapping设置order,contentNegotiationManager,解析enable-matrix-variables并设置removeSemicolonContent属性
4、调用configurePathMatchingProperties设置RequestMappingHandlerMapping属性
5、调用MvcNamespaceUtils.registerCorsConfigurations创建mvcCorsConfigurations RootBeanDefinition
6、RequestMappingHandlerMapping添加属性corsConfigurations
7、调用getConversionService
8、调用getValidator获取验证器RuntimeBeanReference
9、调用getMessageCodesResolver
10.构造类型ConfigurableWebBindingInitializer的RootBeanDefinition并设置conversionService,validator,messageCodesResolver属性
11、调用getMessageConverters获取消息转换器
12、调用getArgumentResolvers
13、调用getReturnValueHandlers解析return-value-handlers属性
14、调用getAsyncTimeout解析async-support和default-timeout属性
15、getAsyncExecutor解析async-support,task-executor,task-executor
16、getInterceptors解析async-support,callable-interceptors属性
17、getInterceptors解析async-support,deferred-result-interceptors属性
18、创建类型为RequestMappingHandlerAdapter的RootBeanDefinition并设置contentNegotiationManager,webBindingInitializer,messageConverters属性
19、调用addRequestBodyAdvice,如果jackson2Present为true,则RequestMappingHandlerAdapter添加类型为JsonViewRequestBodyAdvice的RootBeanDefinition属性
20、调用addResponseBodyAdvice,如果jackson2Present为true,则RequestMappingHandlerAdapter添加类型为JsonViewResponseBodyAdvice的RootBeanDefinition属性
21、解析RequestMappingHandlerAdapter相应属性
22、创建类型为CompositeUriComponentsContributorFactoryBean的RootBeanDefinition
23、创建类型为ConversionServiceExposingInterceptor的RootBeanDefinition
24、创建类型为MappedInterceptor的RootBeanDefinition
25、创建类型为ExceptionHandlerExceptionResolver的RootBeanDefinition
26、创建类型是ResponseStatusExceptionResolver的RootBeanDefinition
27、创建类型是DefaultHandlerExceptionResolver的RootBeanDefinition
28、调用MvcNamespaceUtils.registerDefaultComponents

getContentNegotiationManager(Element element, @Nullable Object source, ParserContext context)

private RuntimeBeanReference getContentNegotiationManager(
		Element element, @Nullable Object source, ParserContext context) {

	RuntimeBeanReference beanRef;
	if (element.hasAttribute("content-negotiation-manager")) {
		String name = element.getAttribute("content-negotiation-manager");
		beanRef = new RuntimeBeanReference(name);
	}
	else {
		RootBeanDefinition factoryBeanDef = new RootBeanDefinition(ContentNegotiationManagerFactoryBean.class);
		factoryBeanDef.setSource(source);
		factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes());
		String name = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME;
		context.getReaderContext().getRegistry().registerBeanDefinition(name, factoryBeanDef);
		context.registerComponent(new BeanComponentDefinition(factoryBeanDef, name));
		beanRef = new RuntimeBeanReference(name);
	}
	return beanRef;
}

1、如果存在content-negotiation-manager属性,返回RuntimeBeanReference
2、创建ContentNegotiationManagerFactoryBean类型的RootBeanDefinition,并设置属性

configurePathMatchingProperties(RootBeanDefinition handlerMappingDef, Element element, ParserContext context)

private void configurePathMatchingProperties(
		RootBeanDefinition handlerMappingDef, Element element, ParserContext context) {

	Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
	if (pathMatchingElement != null) {
		Object source = context.extractSource(element);

		if (pathMatchingElement.hasAttribute("suffix-pattern")) {
			Boolean useSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("suffix-pattern"));
			handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch);
		}
		if (pathMatchingElement.hasAttribute("trailing-slash")) {
			Boolean useTrailingSlashMatch = Boolean.valueOf(pathMatchingElement.getAttribute("trailing-slash"));
			handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch);
		}
		if (pathMatchingElement.hasAttribute("registered-suffixes-only")) {
			Boolean useRegisteredSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("registered-suffixes-only"));
			handlerMappingDef.getPropertyValues().add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch);
		}

		RuntimeBeanReference pathHelperRef = null;
		if (pathMatchingElement.hasAttribute("path-helper")) {
			pathHelperRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-helper"));
		}
		pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(pathHelperRef, context, source);
		handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef);

		RuntimeBeanReference pathMatcherRef = null;
		if (pathMatchingElement.hasAttribute("path-matcher")) {
			pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher"));
		}
		pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, context, source);
		handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
	}
}

1、获取path-matching元素解析成Element
2、如果Element不为null,解析xml配置中suffix-pattern属性设置到handlerMappingDef的useSuffixPatternMatch属性中,解析xml配置中trailing-slash属性设置到handlerMappingDef的useTrailingSlashMatch属性中,解析xml配置中registered-suffixes-only属性设置到handlerMappingDef的useRegisteredSuffixPatternMatch属性中,解析xml配置中path-helper属性成RuntimeBeanReference设置到handlerMappingDef的urlPathHelper属性中,解析xml配置中path-matcher属性成RuntimeBeanReference设置到handlerMappingDef的pathMatcher属性中

MvcNamespaceUtils.registerCorsConfigurations(@Nullable Map<String, CorsConfiguration> corsConfigurations,ParserContext context, @Nullable Object source)

	public static RuntimeBeanReference registerCorsConfigurations(
		@Nullable Map<String, CorsConfiguration> corsConfigurations,
		ParserContext context, @Nullable Object source) {

	if (!context.getRegistry().containsBeanDefinition(CORS_CONFIGURATION_BEAN_NAME)) {
		RootBeanDefinition corsDef = new RootBeanDefinition(LinkedHashMap.class);
		corsDef.setSource(source);
		corsDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		if (corsConfigurations != null) {
			corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations);
		}
		context.getReaderContext().getRegistry().registerBeanDefinition(CORS_CONFIGURATION_BEAN_NAME, corsDef);
		context.registerComponent(new BeanComponentDefinition(corsDef, CORS_CONFIGURATION_BEAN_NAME));
	}
	else if (corsConfigurations != null) {
		BeanDefinition corsDef = context.getRegistry().getBeanDefinition(CORS_CONFIGURATION_BEAN_NAME);
		corsDef.getConstructorArgumentValues().addIndexedArgumentValue(0, corsConfigurations);
	}
	return new RuntimeBeanReference(CORS_CONFIGURATION_BEAN_NAME);
}

1、如果context不包含名为mvcCorsConfigurations的BeanDefinition,创建类型是LinkedHashMap的名为mvcCorsConfigurations的RootBeanDefinition并注册
2、如果corsConfigurations不为null,从context中获取名为mvcCorsConfigurations的BeanDefinition,将corsConfigurations作为参数添加到其中
3、返回名为mvcCorsConfigurations的RuntimeBeanReference

getConversionService(Element element, @Nullable Object source, ParserContext context)

	private RuntimeBeanReference getConversionService(Element element, @Nullable Object source, ParserContext context) {
	RuntimeBeanReference conversionServiceRef;
	if (element.hasAttribute("conversion-service")) {
		conversionServiceRef = new RuntimeBeanReference(element.getAttribute("conversion-service"));
	}
	else {
		RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class);
		conversionDef.setSource(source);
		conversionDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		String conversionName = context.getReaderContext().registerWithGeneratedName(conversionDef);
		context.registerComponent(new BeanComponentDefinition(conversionDef, conversionName));
		conversionServiceRef = new RuntimeBeanReference(conversionName);
	}
	return conversionServiceRef;
}

1、判断是否有conversion-service属性,若有则获取conversion-service,返回RuntimeBeanReference
2、构造类型为FormattingConversionServiceFactoryBean的RootBeanDefinition

getValidator(Element element, @Nullable Object source, ParserContext context)

private RuntimeBeanReference getValidator(Element element, @Nullable Object source, ParserContext context) {
	if (element.hasAttribute("validator")) {
		return new RuntimeBeanReference(element.getAttribute("validator"));
	}
	else if (javaxValidationPresent) {
		RootBeanDefinition validatorDef = new RootBeanDefinition(
				"org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean");
		validatorDef.setSource(source);
		validatorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		String validatorName = context.getReaderContext().registerWithGeneratedName(validatorDef);
		context.registerComponent(new BeanComponentDefinition(validatorDef, validatorName));
		return new RuntimeBeanReference(validatorName);
	}
	else {
		return null;
	}
}

1、判断是否有validator属性,若有则获取validator,返回RuntimeBeanReference
2、如果javaxValidationPresent为true构造类型为org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean的RootBeanDefinition
3、否则返回null

getMessageCodesResolver(Element element)

private RuntimeBeanReference getMessageCodesResolver(Element element) {
	if (element.hasAttribute("message-codes-resolver")) {
		return new RuntimeBeanReference(element.getAttribute("message-codes-resolver"));
	}
	else {
		return null;
	}
}

如果有message-codes-resolver,则获取该属性并返回RuntimeBeanReference,否则返回null。

getMessageConverters(Element element, @Nullable Object source, ParserContext context)

private ManagedList<?> getMessageConverters(Element element, @Nullable Object source, ParserContext context) {
	Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
	ManagedList<Object> messageConverters = new ManagedList<>();
	if (convertersElement != null) {
		messageConverters.setSource(source);
		for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
			Object object = context.getDelegate().parsePropertySubElement(beanElement, null);
			messageConverters.add(object);
		}
	}

	if (convertersElement == null || Boolean.parseBoolean(convertersElement.getAttribute("register-defaults"))) {
		messageConverters.setSource(source);
		messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));

		RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
		stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
		messageConverters.add(stringConverterDef);

		messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
		messageConverters.add(createConverterDefinition(ResourceRegionHttpMessageConverter.class, source));
		messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
		messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));

		if (romePresent) {
			messageConverters.add(createConverterDefinition(AtomFeedHttpMessageConverter.class, source));
			messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source));
		}

		if (jackson2XmlPresent) {
			Class<?> type = MappingJackson2XmlHttpMessageConverter.class;
			RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
			GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
			jacksonFactoryDef.getPropertyValues().add("createXmlMapper", true);
			jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
			messageConverters.add(jacksonConverterDef);
		}
		else if (jaxb2Present) {
			messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
		}

		if (jackson2Present) {
			Class<?> type = MappingJackson2HttpMessageConverter.class;
			RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
			GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
			jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
			messageConverters.add(jacksonConverterDef);
		}
		else if (gsonPresent) {
			messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
		}

		if (jackson2SmilePresent) {
			Class<?> type = MappingJackson2SmileHttpMessageConverter.class;
			RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
			GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
			jacksonFactoryDef.getPropertyValues().add("factory", new SmileFactory());
			jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
			messageConverters.add(jacksonConverterDef);
		}
		if (jackson2CborPresent) {
			Class<?> type = MappingJackson2CborHttpMessageConverter.class;
			RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
			GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
			jacksonFactoryDef.getPropertyValues().add("factory", new CBORFactory());
			jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
			messageConverters.add(jacksonConverterDef);
		}
	}
	return messageConverters;
}

1、获取名为message-converters的Element
2、如果Element不为空,获取message-converters子标签下的bean或ref的元素解析后并添加到messageConverters集合中
3、如果convertersElement为null或者register-defaults属性为true,则
创建类型是ByteArrayHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
创建类型是StringHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
创建类型是ResourceHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
创建类型是ResourceRegionHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
创建类型是SourceHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
创建类型是AllEncompassingFormHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合

如果romePresent为true,则创建类型是AtomFeedHttpMessageConverter,RssChannelHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
如果jackson2XmlPresent为true则创建类型是MappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperFactoryBean作为MappingJackson2XmlHttpMessageConverter参数)的RootBeanDefinition并添加到messageConverters集合
如果jaxb2Present为true,则创建类型是Jaxb2RootElementHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
如果jackson2Present为true,则创建类型是MappingJackson2HttpMessageConverter(Jackson2ObjectMapperFactoryBean作为参数)的RootBeanDefinition并添加到messageConverters集合
如果gsonPresent为true,则创建类型GsonHttpMessageConverter的RootBeanDefinition并添加到messageConverters集合
如果jackson2SmilePresent为true,则创建类型是MappingJackson2SmileHttpMessageConverter(Jackson2ObjectMapperFactoryBean作为参数)的RootBeanDefinition并添加到messageConverters集合
如果jackson2CborPresent为true,则创建类型是MappingJackson2CborHttpMessageConverter(Jackson2ObjectMapperFactoryBean作为参数)的RootBeanDefinition并添加到messageConverters集合

MessageConverter可参考https://blog.csdn.net/lianghecai52171314/article/details/106315408

MvcNamespaceUtils.registerDefaultComponents(ParserContext context, @Nullable Object source)

	public static void registerDefaultComponents(ParserContext context, @Nullable Object source) {
	registerBeanNameUrlHandlerMapping(context, source); // 创建类型是BeanNameUrlHandlerMapping的RootBeanDefinition
	registerHttpRequestHandlerAdapter(context, source); // 创建类型是HttpRequestHandlerAdapter的RootBeanDefinition
	registerSimpleControllerHandlerAdapter(context, source); // 创建类型是SimpleControllerHandlerAdapter的RootBeanDefinition
	registerHandlerMappingIntrospector(context, source); // 创建类型是HandlerMappingIntrospector的RootBeanDefinition
	registerLocaleResolver(context, source); //创建类型是AcceptHeaderLocaleResolver的RootBeanDefinition
	registerThemeResolver(context, source); //创建类型是FixedThemeResolver的RootBeanDefinition
	registerViewNameTranslator(context, source); //创建类型是DefaultRequestToViewNameTranslator的RootBeanDefinition
	registerFlashMapManager(context, source); //创建类型是SessionFlashMapManager的RootBeanDefinition
}
posted @   shigp1  阅读(133)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示