SpringMVC之分析AnnotationDrivenBeanDefinitionParser(三)

简介: 我们在之前的文章中对这篇文章中AnnotationDrivenBeanDefinitionParser的parse方法进行了一些分析,我们在这篇文章中接着分析AnnotationDrivenBeanDefinitionParser的parse方法的内容。

我们在之前的文章中对这篇文章中AnnotationDrivenBeanDefinitionParser的parse方法进行了一些分析,我们在这篇文章中接着分析AnnotationDrivenBeanDefinitionParser的parse方法的内容。

ManagedList<?> messageConverters = getMessageConverters(element, source, parserContext);
	private ManagedList<?> getMessageConverters(Element element, Object source, ParserContext parserContext) {
		//解析message-converters的标签
		//格式如下:
		/*
		    <mvc:annotation-driven>
				<mvc:message-converters>
					<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
					<bean class="org.springframework.http.converter.StringHttpMessageConverter">
						<property name="supportedMediaTypes">
							<list>
								<value>text/html;charset=UTF-8</value>
								<value>application/javascript;charset=UTF-8</value>
							</list>
						</property>
					</bean>
				</mvc:message-converters>
			</mvc:annotation-driven>
		*/
		Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
		//存放自己配置的HttpMessageConverter
		ManagedList<? super Object> messageConverters = new ManagedList<Object>();
		if (convertersElement != null) {
			messageConverters.setSource(source);
			//解析自己配置的HttpMessageConverter的bean
			for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
				Object object = parserContext.getDelegate().parsePropertySubElement(beanElement, null);
				messageConverters.add(object);
			}
		}
		//如果没有配置<mvc:message-converters>或者register-defaults的值为true 默认为true
		if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) {
			messageConverters.setSource(source);
			//添加ByteArrayHttpMessageConverter的BeanDefinition
			messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));
			//添加StringHttpMessageConverter的BeanDefinition
			RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
			stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
			messageConverters.add(stringConverterDef);
			//添加ResourceHttpMessageConverter的BeanDefinition
			messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
			//添加SourceHttpMessageConverter的BeanDefinition
			messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
			//添加AllEncompassingFormHttpMessageConverter的BeanDefinition
			messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));
			//如果有Classpath下面有 com.rometools.rome.feed.WireFeed,则添加
			//AtomFeedHttpMessageConverter和RssChannelHttpMessageConverter的BeanDefinition
			if (romePresent) {
				messageConverters.add(createConverterDefinition(AtomFeedHttpMessageConverter.class, source));
				messageConverters.add(createConverterDefinition(RssChannelHttpMessageConverter.class, source));
			}
			//如果有Classpath下面有 com.fasterxml.jackson.dataformat.xml.XmlMapper,则添加
			//MappingJackson2XmlHttpMessageConverter和RssChannelHttpMessageConverter的BeanDefinition
			if (jackson2XmlPresent) {
				RootBeanDefinition jacksonConverterDef = createConverterDefinition(MappingJackson2XmlHttpMessageConverter.class, source);
				//创建Jackson2ObjectMapperFactoryBean的BeanDefinition
				GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
				jacksonFactoryDef.getPropertyValues().add("createXmlMapper", true);
				jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
				messageConverters.add(jacksonConverterDef);
			}
			//如果有Classpath下面有 javax.xml.bind.Binder,则添加
			//Jaxb2RootElementHttpMessageConverter的BeanDefinition
			else if (jaxb2Present) {
				messageConverters.add(createConverterDefinition(Jaxb2RootElementHttpMessageConverter.class, source));
			}
			//如果有Classpath下面有 com.fasterxml.jackson.databind.ObjectMapper和Jaxb2RootElementHttpMessageConverter的BeanDefinition,则添加
			//MappingJackson2HttpMessageConverter的BeanDefinition
			if (jackson2Present) {
				RootBeanDefinition jacksonConverterDef = createConverterDefinition(MappingJackson2HttpMessageConverter.class, source);
				//创建Jackson2ObjectMapperFactoryBean的BeanDefinition
				GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
				//添加到MappingJackson2HttpMessageConverter的构造函数中
				jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
				messageConverters.add(jacksonConverterDef);
			}
			//如果有Classpath下面有 com.google.gson.Gson,则添加
			//GsonHttpMessageConverter的BeanDefinition
			else if (gsonPresent) {
				messageConverters.add(createConverterDefinition(GsonHttpMessageConverter.class, source));
			}
		}
		return messageConverters;
	}
上面的这段内容主要是添加一些自己配置的HttpMessageConverter的BeanDefinition或者是一些初始化的HttpMessageConverter的BeanDefinition
ManagedList<?> argumentResolvers = getArgumentResolvers(element, parserContext);

这一段的内容主要是获取自定义的一些参数解析器(HandlerMethodArgumentResolver的实现类)

ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, parserContext);
这一段是配置自定义的HandlerMethodReturnValueHandler的实现类,没什么可说的。标签如下:

        <mvc:return-value-handlers>
        </mvc:return-value-handlers>
		String asyncTimeout = getAsyncTimeout(element);
		RuntimeBeanReference asyncExecutor = getAsyncExecutor(element);
		ManagedList<?> callableInterceptors = getCallableInterceptors(element, source, parserContext);
		ManagedList<?> deferredResultInterceptors = getDeferredResultInterceptors(element, source, parserContext);
上面这一段是配置异步的请求处理信息。

		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);
上面这一段是创建RequestMappingHandlerAdapter的BeanDefinition。并给webBindingInitializer属性和messageConverters属性赋值,赋值的内容是前面获取的的Bean对象。

addRequestBodyAdvice(handlerAdapterDef);
	protected void addRequestBodyAdvice(RootBeanDefinition beanDef) {
		//如果Classpath下面有com.fasterxml.jackson.databind.ObjectMapper和
		//com.fasterxml.jackson.core.JsonGenerator这两个类的话,则添加JsonViewRequestBodyAdvice到
		//requestResponseBodyAdvice集合中
		if (jackson2Present) {
			beanDef.getPropertyValues().add("requestBodyAdvice",
					new RootBeanDefinition(JsonViewRequestBodyAdvice.class));
		}
	}
上面的这段代码中是给RequestHandlerMappingAdapter的requestResponseBodyAdvice属性中添加值。

addResponseBodyAdvice(handlerAdapterDef);
	protected void addResponseBodyAdvice(RootBeanDefinition beanDef) {
		//如果Classpath下面有com.fasterxml.jackson.databind.ObjectMapper和
		//com.fasterxml.jackson.core.JsonGenerator这两个类的话,则添加JsonViewResponseBodyAdvice到
		//requestResponseBodyAdvice集合中
		if (jackson2Present) {
			beanDef.getPropertyValues().add("responseBodyAdvice",
					new RootBeanDefinition(JsonViewResponseBodyAdvice.class));
		}
	}
-上面的这段代码中是给RequestHandlerMappingAdapter的requestResponseBodyAdvice属性中添加值。
		if (argumentResolvers != null) {
			handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
		}
		if (returnValueHandlers != null) {
			handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
		}
给RequestHandlerMappingAdapter中的customArgumentResolvers添加自定义的参数解析器。给RequestHandlerMappingAdapter中的customReturnValueHandlers添加自定义的参数返回处理器。
readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME , handlerAdapterDef);
将创建的RequestMappingHandlerAdapter注册到IOC容器中。bean的name为org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter。

在AnnotationDrivenBeanDefinitionParser中还添加了其他的一些Bean到IOC容器中,下面我们挑一些我们熟悉的说一下:

		RootBeanDefinition exceptionHandlerExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
		exceptionHandlerExceptionResolver.setSource(source);
		exceptionHandlerExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		exceptionHandlerExceptionResolver.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
		exceptionHandlerExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
		exceptionHandlerExceptionResolver.getPropertyValues().add("order", 0);
		addResponseBodyAdvice(exceptionHandlerExceptionResolver);

		if (argumentResolvers != null) {
			exceptionHandlerExceptionResolver.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
		}
		if (returnValueHandlers != null) {
			exceptionHandlerExceptionResolver.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
		}
添加ExceptionHandlerExceptionResolver,处理异常信息的。
		RootBeanDefinition responseStatusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
		responseStatusExceptionResolver.setSource(source);
		responseStatusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		responseStatusExceptionResolver.getPropertyValues().add("order", 1);
		String responseStatusExceptionResolverName =
				readerContext.registerWithGeneratedName(responseStatusExceptionResolver);
异常信息的另外一种处理方式,将异常信息映射为HTTP状态码。

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

默认的异常信息解析器。这三个异常信息解析器的处理顺序是:ExceptionHandlerExceptionResolver最先,ResponseStatusExceptionResolver次之,DefaultHandlerExceptionResolver顺序为最后。

MvcNamespaceUtils.registerDefaultComponents(parserContext, source);
这这一段代码总主要是添加默认的几个Bean,分别是:BeanNameUrlHandlerMapping、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter。

相关文章
|
前端开发 Java Spring
SpringMVC之分析AnnotationDrivenBeanDefinitionParser(二)
在上一篇文章中我们简单的分析了一下AnnotationDrivenBeanDefinitionParser,在这一篇的文章中我们继续分析AnnotationDrivenBeanDefinitionParser的内容。
1164 0
|
前端开发 Java Spring
SpringMVC之分析AnnotationDrivenBeanDefinitionParser(一)
首先我们会想一下,我们在进行SpringMVC配置的时候是怎样配置的(不是web.xml)?我们会在SpringMVC的配置文件中添加这样的一些东西: xmlns:mvc="http://www.
1288 0
|
6月前
|
设计模式 前端开发 JavaScript
Spring MVC(一)【什么是Spring MVC】
Spring MVC(一)【什么是Spring MVC】
|
5月前
|
设计模式 前端开发 Java
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
76 1
|
5月前
|
前端开发 Java 应用服务中间件
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
Spring框架第六章(SpringMVC概括及基于JDK21与Tomcat10创建SpringMVC程序)
|
6月前
|
前端开发 Java 关系型数据库
基于ssm框架旅游网旅游社交平台前后台管理系统(spring+springmvc+mybatis+maven+tomcat+html)
基于ssm框架旅游网旅游社交平台前后台管理系统(spring+springmvc+mybatis+maven+tomcat+html)
|
5月前
|
XML Java 数据格式
SpringMVC的XML配置解析-spring18
SpringMVC的XML配置解析-spring18
|
5月前
|
应用服务中间件
从代码角度戳一下springMVC的运行过程-spring16
从代码角度戳一下springMVC的运行过程-spring16
|
前端开发 Java Go
Spring MVC 和 Spring Boot 的区别
Spring MVC 和 Spring Boot 的区别
219 0
|
6月前
|
移动开发 Java 测试技术
Spring MVC+Spring+Mybatis实现支付宝支付功能(附完整代码)
Spring MVC+Spring+Mybatis实现支付宝支付功能(附完整代码)
162 1