SpringMVC5源码AnnotationDrivenBeanDefinitionParser注解解析器

    mvc:annotation-driven节点的解析器,是springmvc的核心解析器。AnnotationDrivenBeanDefinitionParser类包路径是org.springframework.web.servlet.config,继承于BeanDefinitionParser接口。

1、说明

         通过AnnotationDrivenBeanDefinitionParser注解解析器源码发现,主要注册HandlerMappings-路径匹配器、HandlerAdapters-路径匹配适配器、HandlerExceptionResolvers-异常解析器、AntPathMatcher-路径解析器、UrlPathHelper-请求路径获取帮助类等beans,提前为mvc做好基础的准备。

        AnnotationDrivenBeanDefinitionParser注解解析器注入了类包括:RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、RequestMappingHandlerAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver。

2、parse()方法

2.1、registerComponent

跟官方注释提及的一样,主要目的是注册与mvc处理有关的相关beans以及默认的mvc组件.

parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
parserContext.registerComponent(new BeanComponentDefinition(uriContributorDef, uriContributorName));
parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName));
//格式转换处理拦截类,比如时间、数字等
parserContext.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExResolverName));
parserContext.registerComponent(new BeanComponentDefinition(statusExceptionResolver, statusExResolverName));
parserContext.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExResolverName));

2.2、组件注册

组件注册对应parse()方法的代码片段如下

//生成RequestMappingHandlerMapping组件对象
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
handlerMappingDef.setSource(source);
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//优先级设置为最高
handlerMappingDef.getPropertyValues().add("order", 0);
handlerMappingDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
//查看mvc:annotation-driven有无enable-matrix-variables/enableMatrixVariables,表示是否开启多变量映射比如/user;name=zhangsan;pwd=123
if (element.hasAttribute("enable-matrix-variables")) {
	Boolean enableMatrixVariables = Boolean.valueOf(element.getAttribute("enable-matrix-variables"));
	handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
}
//配置路径匹配解析器等属性
configurePathMatchingProperties(handlerMappingDef, element, parserContext);

4、getMessageConverters方法

自定义的一些参数解析器(HandlerMethodArgumentResolver的实现类)

//parse方法中的
ManagedList<?> messageConverters = getMessageConverters(element, source, parserContext);

 

private ManagedList<?> getMessageConverters(Element element, @Nullable Object source, ParserContext parserContext) {
Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
//存放自己配置的HttpMessageConverter
ManagedList<? super Object> messageConverters = new ManagedList<>();
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(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));
		}
//如果有Classpath下面有 com.fasterxml.jackson.dataformat.xml.XmlMapper,则添加
//MappingJackson2XmlHttpMessageConverter和RssChannelHttpMessageConverter的BeanDefinition
	if (jackson2XmlPresent) {
		Class<?> type = MappingJackson2XmlHttpMessageConverter.class;
      //创建Jackson2ObjectMapperFactoryBean的BeanDefinition
		RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
		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) {
	Class<?> type = MappingJackson2HttpMessageConverter.class;
		RootBeanDefinition jacksonConverterDef = createConverterDefinition(type, source);
		GenericBeanDefinition jacksonFactoryDef = createObjectMapperFactoryDefinition(source);
				jacksonConverterDef.getConstructorArgumentValues().addIndexedArgumentValue(0, jacksonFactoryDef);
		messageConverters.add(jacksonConverterDef);
	}
//如果有Classpath下面有 com.google.gson.Gson,则添加
//GsonHttpMessageConverter的BeanDefinition
  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;
	}

以上代码对应了下面

private static final boolean javaxValidationPresent =
ClassUtils.isPresent("javax.validation.Validator",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static boolean romePresent =
ClassUtils.isPresent("com.rometools.rome.feed.WireFeed",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static final boolean jaxb2Present =
	ClassUtils.isPresent("javax.xml.bind.Binder",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static final boolean jackson2Present =
	ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
		AnnotationDrivenBeanDefinitionParser.class.getClassLoader()) &&
		ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static final boolean jackson2XmlPresent =
	ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static final boolean jackson2SmilePresent =
	ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static final boolean jackson2CborPresent =
ClassUtils.isPresent("com.fasterxml.jackson.dataformat.cbor.CBORFactory",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

private static final boolean gsonPresent =
ClassUtils.isPresent("com.google.gson.Gson",AnnotationDrivenBeanDefinitionParser.class.getClassLoader());

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值