我们在之前的文章中对这篇文章中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。