Spring 源码解析八:Xml 配置中默认的命名空间处理器

x33g5p2x  于2022-02-11 发布在 Spring  
字(42.8k)|赞(0)|评价(0)|浏览(471)

在 Spring 源码解析五:Bean 的配置、定义、注册 中,有一些 Xml 配置中默认的命名空间处理器还未解析

这里只解析常用的几个

  • SimpleConstructorNamespaceHandler
  • SimplePropertyNamespaceHandler
  • ContextNamespaceHandler
  • TaskNamespaceHandler
  • CacheNamespaceHandler
  • MvcNamespaceHandler

其他的有兴趣可以自行探索

1. SimpleConstructorNamespaceHandler

SimpleConstructorNamespaceHandler
的主要功能是在实例化如下配置的 bean

  1. <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/>

name="Enescu", work=bean[compositions] 作为构造函数的参数实例化 bean

  1. public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
  2. @Override
  3. public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
  4. if (node instanceof Attr) {
  5. Attr attr = (Attr) node;
  6. // 去除两边空白
  7. String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
  8. // 去除两边空白
  9. String argValue = StringUtils.trimWhitespace(attr.getValue());
  10. // 构造函数参数集合
  11. ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
  12. boolean ref = false;
  13. // 如果字段名以"-ref"结果,则表示在运行时对其他bean的引用
  14. if (argName.endsWith(REF_SUFFIX)) {
  15. ref = true;
  16. argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
  17. }
  18. // 用ValueHolder封装值
  19. ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
  20. valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));
  21. // 以"_"开头的,表示是没有名字的参数,按照顺序传入就可以了
  22. if (argName.startsWith(DELIMITER_PREFIX)) {
  23. String arg = argName.substring(1).trim();
  24. // 如果没有指定顺序,直接添加
  25. if (!StringUtils.hasText(arg)) {
  26. cvs.addGenericArgumentValue(valueHolder);
  27. }
  28. // 如果有指定顺序,指定顺序添加
  29. else {
  30. int index = -1;
  31. try {
  32. index = Integer.parseInt(arg);
  33. }
  34. catch (NumberFormatException ex) {
  35. // ... 代码省略
  36. }
  37. // ... 代码省略
  38. // 添加进cvs
  39. cvs.addIndexedArgumentValue(index, valueHolder);
  40. }
  41. }
  42. // 有名字的参数
  43. else {
  44. // ... 代码省略
  45. // 添加进cvs
  46. valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
  47. cvs.addGenericArgumentValue(valueHolder);
  48. }
  49. }
  50. return definition;
  51. }
  52. }

2. SimplePropertyNamespaceHandler

SimplePropertyNamespaceHandler
的主要功能是在实例化如下配置的 bean

  1. <bean id="rob" class="..TestBean" p:name="Rob Harrop" p:spouse-ref="sally"/>

name="Rob Harrop", spouse=bean[sally] 作为属性注入到 bean 中

  1. public class SimplePropertyNamespaceHandler implements NamespaceHandler {
  2. @Override
  3. public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
  4. if (node instanceof Attr) {
  5. Attr attr = (Attr) node;
  6. // 属性名
  7. String propertyName = parserContext.getDelegate().getLocalName(attr);
  8. // 属性值
  9. String propertyValue = attr.getValue();
  10. // 属性集合
  11. MutablePropertyValues pvs = definition.getBeanDefinition().getPropertyValues();
  12. // 如果字段名以"-ref"结果,则表示在运行时对其他bean的引用
  13. if (propertyName.endsWith(REF_SUFFIX)) {
  14. propertyName = propertyName.substring(0, propertyName.length() - REF_SUFFIX.length());
  15. // 把字段名从短横线-或下划线_式的,转化为驼峰式的
  16. pvs.add(Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue));
  17. }
  18. else {
  19. // 把字段名从短横线-或下划线_式的,转化为驼峰式的
  20. pvs.add(Conventions.attributeNameToPropertyName(propertyName), propertyValue);
  21. }
  22. }
  23. return definition;
  24. }
  25. }

3. ContextNamespaceHandler

  1. public class ContextNamespaceHandler extends NamespaceHandlerSupport {
  2. @Override
  3. public void init() {
  4. registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
  5. registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
  6. registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
  7. registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
  8. registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
  9. registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
  10. registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
  11. registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
  12. }
  13. }

3.1. context:property-placeholder

PropertyPlaceholderBeanDefinitionParser
的主要功能是解析<context:property-placeholder/>元素,在 bean 定义时,使用 ${} 引用外部来源的属性

先看看继承关系

  1. - AbstractBeanDefinitionParser
  2. - AbstractSingleBeanDefinitionParser
  3. - AbstractPropertyLoadingBeanDefinitionParser
  4. - PropertyPlaceholderBeanDefinitionParser

3.1.1. AbstractBeanDefinitionParser

AbstractBeanDefinitionParser
的主要功能是实现了 BeanDefinitionParser
接口的 parse 方法,提供了基本的由配置解析为对象的功能

  1. public abstract class AbstractBeanDefinitionParser implements BeanDefinitionParser {
  2. @Override
  3. public final BeanDefinition parse(Element element, ParserContext parserContext) {
  4. // 解析元素
  5. AbstractBeanDefinition definition = parseInternal(element, parserContext);
  6. try {
  7. // 获取bean的id
  8. String id = resolveId(element, definition, parserContext);
  9. String[] aliases = null;
  10. // 获取name属性,用逗号分隔为多个别名
  11. if (shouldParseNameAsAliases()) {
  12. String name = element.getAttribute(NAME_ATTRIBUTE);
  13. if (StringUtils.hasLength(name)) {
  14. aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
  15. }
  16. }
  17. // 封装为BeanDefinitionHolder
  18. BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
  19. // 注册到registry中
  20. registerBeanDefinition(holder, parserContext.getRegistry());
  21. // ... 代码省略
  22. }
  23. catch (BeanDefinitionStoreException ex) {
  24. // ... 代码省略
  25. }
  26. return definition;
  27. }
  28. // 解析元素,由子类实现
  29. protected abstract AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext);
  30. // 获取bean的id,先获取id属性,其次name属性,都没有,生成默认的名字
  31. protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
  32. throws BeanDefinitionStoreException {
  33. // ... 代码省略
  34. }
  35. }

3.1.2. AbstractSingleBeanDefinitionParser

AbstractSingleBeanDefinitionParser
的主要功能是支持解析为单例的 bean

  1. public abstract class AbstractSingleBeanDefinitionParser extends AbstractBeanDefinitionParser {
  2. @Override
  3. protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
  4. // 创建一个构造器
  5. BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
  6. // 父元素
  7. String parentName = getParentName(element);
  8. if (parentName != null) {
  9. builder.getRawBeanDefinition().setParentName(parentName);
  10. }
  11. // beanClass
  12. Class<?> beanClass = getBeanClass(element);
  13. if (beanClass != null) {
  14. builder.getRawBeanDefinition().setBeanClass(beanClass);
  15. }
  16. // beanClassName
  17. else {
  18. String beanClassName = getBeanClassName(element);
  19. if (beanClassName != null) {
  20. builder.getRawBeanDefinition().setBeanClassName(beanClassName);
  21. }
  22. }
  23. // ... 代码省略
  24. // 解析到构造器
  25. doParse(element, parserContext, builder);
  26. return builder.getBeanDefinition();
  27. }
  28. // 解析到构造器,由子类实现
  29. protected void doParse(Element element, BeanDefinitionBuilder builder) {}
  30. }

3.1.3. AbstractPropertyLoadingBeanDefinitionParser

AbstractPropertyLoadingBeanDefinitionParser
的主要功能是解析context:property-...元素

  1. abstract class AbstractPropertyLoadingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
  2. @Override
  3. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  4. // location属性
  5. String location = element.getAttribute("location");
  6. if (StringUtils.hasLength(location)) {
  7. location = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(location);
  8. String[] locations = StringUtils.commaDelimitedListToStringArray(location);
  9. builder.addPropertyValue("locations", locations);
  10. }
  11. // properties-ref属性
  12. String propertiesRef = element.getAttribute("properties-ref");
  13. if (StringUtils.hasLength(propertiesRef)) {
  14. builder.addPropertyReference("properties", propertiesRef);
  15. }
  16. // file-encoding属性
  17. String fileEncoding = element.getAttribute("file-encoding");
  18. if (StringUtils.hasLength(fileEncoding)) {
  19. builder.addPropertyValue("fileEncoding", fileEncoding);
  20. }
  21. // order属性
  22. String order = element.getAttribute("order");
  23. if (StringUtils.hasLength(order)) {
  24. builder.addPropertyValue("order", Integer.valueOf(order));
  25. }
  26. // ignore-resource-not-found属性
  27. builder.addPropertyValue("ignoreResourceNotFound",
  28. Boolean.valueOf(element.getAttribute("ignore-resource-not-found")));
  29. // local-override属性
  30. builder.addPropertyValue("localOverride",
  31. Boolean.valueOf(element.getAttribute("local-override")));
  32. }
  33. }

3.1.4. PropertyPlaceholderBeanDefinitionParser

PropertyPlaceholderBeanDefinitionParser
的主要功能是解析context:property-placeholder元素

  1. class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
  2. @Override
  3. protected Class<?> getBeanClass(Element element) {
  4. // 使用这个类来实现bean
  5. return org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class;
  6. }
  7. @Override
  8. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  9. super.doParse(element, parserContext, builder);
  10. // ignore-unresolvable属性
  11. builder.addPropertyValue("ignoreUnresolvablePlaceholders",
  12. Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
  13. // system-properties-mode属性
  14. String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE);
  15. if (StringUtils.hasLength(systemPropertiesModeName) &&
  16. !systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) {
  17. builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_" + systemPropertiesModeName);
  18. }
  19. // value-separator属性
  20. if (element.hasAttribute("value-separator")) {
  21. builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
  22. }
  23. // trim-values属性
  24. if (element.hasAttribute("trim-values")) {
  25. builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
  26. }
  27. // null-value属性
  28. if (element.hasAttribute("null-value")) {
  29. builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
  30. }
  31. }
  32. }

3.2. context:property-override

PropertyOverrideBeanDefinitionParser
的主要功能是解析<context:property-override/>元素,为 xml 配置文件中的 bean 的属性指定最终结果

  1. class PropertyOverrideBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
  2. @Override
  3. protected Class<?> getBeanClass(Element element) {
  4. // 使用这个类来实现bean
  5. return PropertyOverrideConfigurer.class;
  6. }
  7. @Override
  8. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  9. super.doParse(element, parserContext, builder);
  10. // ignore-unresolvable属性
  11. builder.addPropertyValue("ignoreInvalidKeys",
  12. Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
  13. }
  14. }

3.3. context:annotation-config

AnnotationConfigBeanDefinitionParser
的主要功能是解析<context:annotation-config/>元素,使用 @Autowired 自动装配 bean

  1. public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
  2. @Override
  3. public BeanDefinition parse(Element element, ParserContext parserContext) {
  4. Object source = parserContext.extractSource(element);
  5. // 获取registry所有相关的bean定义
  6. Set<BeanDefinitionHolder> processorDefinitions =
  7. AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);
  8. // ... 代码省略
  9. // 注册bean定义
  10. for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
  11. parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
  12. }
  13. // ... 代码省略
  14. return null;
  15. }
  16. }

3.4. context:component-scan

ComponentScanBeanDefinitionParser
的主要功能是解析<context:component-scan/>元素,自动扫描指定包下的注解 bean

  1. public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
  2. @Override
  3. public BeanDefinition parse(Element element, ParserContext parserContext) {
  4. // base-package属性
  5. String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
  6. basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
  7. // 分隔多个包
  8. String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
  9. ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
  10. // 创建并配置扫描对象
  11. ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
  12. // 扫描包中的组件
  13. Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
  14. // 注册组件到上下文中
  15. registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
  16. return null;
  17. }
  18. }

关于 context: 命令空间的解析就到这里了,其他的有兴趣可以自行探索

4. TaskNamespaceHandler

  1. public class TaskNamespaceHandler extends NamespaceHandlerSupport {
  2. @Override
  3. public void init() {
  4. this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
  5. this.registerBeanDefinitionParser("executor", new ExecutorBeanDefinitionParser());
  6. this.registerBeanDefinitionParser("scheduled-tasks", new ScheduledTasksBeanDefinitionParser());
  7. this.registerBeanDefinitionParser("scheduler", new SchedulerBeanDefinitionParser());
  8. }
  9. }

4.1. task:annotation-driven

AnnotationDrivenBeanDefinitionParser
的主要功能是解析<task:annotation-driven/>元素,开启定时器开关,自动扫描程序中带注解的定时器

  1. public class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
  2. @Override
  3. public BeanDefinition parse(Element element, ParserContext parserContext) {
  4. Object source = parserContext.extractSource(element);
  5. // ... 代码省略
  6. // 获取registry
  7. BeanDefinitionRegistry registry = parserContext.getRegistry();
  8. // mode属性
  9. String mode = element.getAttribute("mode");
  10. // 使用aspectj来执行异步任务
  11. if ("aspectj".equals(mode)) {
  12. // mode="aspectj"
  13. registerAsyncExecutionAspect(element, parserContext);
  14. }
  15. // 使用内置的功能来执行异步任务
  16. else {
  17. // bean "org.springframework.context.annotation.internalAsyncAnnotationProcessor" 已经存在
  18. if (registry.containsBeanDefinition(TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  19. // ... 代码省略
  20. }
  21. else {
  22. // 使用类 "org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor"
  23. // 来配置bean "org.springframework.context.annotation.internalAsyncAnnotationProcessor"
  24. BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
  25. "org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor");
  26. builder.getRawBeanDefinition().setSource(source);
  27. // executor属性
  28. String executor = element.getAttribute("executor");
  29. if (StringUtils.hasText(executor)) {
  30. builder.addPropertyReference("executor", executor);
  31. }
  32. // exception-handler属性
  33. String exceptionHandler = element.getAttribute("exception-handler");
  34. if (StringUtils.hasText(exceptionHandler)) {
  35. builder.addPropertyReference("exceptionHandler", exceptionHandler);
  36. }
  37. // proxy-target-class属性
  38. if (Boolean.parseBoolean(element.getAttribute(AopNamespaceUtils.PROXY_TARGET_CLASS_ATTRIBUTE))) {
  39. builder.addPropertyValue("proxyTargetClass", true);
  40. }
  41. // 注册组件到registry与上下文
  42. registerPostProcessor(parserContext, builder, TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME);
  43. }
  44. }
  45. // bean "org.springframework.context.annotation.internalScheduledAnnotationProcessor" 已经存在
  46. if (registry.containsBeanDefinition(TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  47. // ... 代码省略
  48. }
  49. else {
  50. // 使用类 "org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor"
  51. // 来配置bean "org.springframework.context.annotation.internalScheduledAnnotationProcessor"
  52. BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
  53. "org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor");
  54. builder.getRawBeanDefinition().setSource(source);
  55. // scheduler属性
  56. String scheduler = element.getAttribute("scheduler");
  57. if (StringUtils.hasText(scheduler)) {
  58. builder.addPropertyReference("scheduler", scheduler);
  59. }
  60. // 注册组件到registry与上下文
  61. registerPostProcessor(parserContext, builder, TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME);
  62. }
  63. // ... 代码省略
  64. return null;
  65. }
  66. // 使用aspectj来执行异步任务
  67. private void registerAsyncExecutionAspect(Element element, ParserContext parserContext) {
  68. // bean "org.springframework.scheduling.config.internalAsyncExecutionAspect" 不存在
  69. if (!parserContext.getRegistry().containsBeanDefinition(TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)) {
  70. // 使用类 "org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect"
  71. // 来配置bean "org.springframework.scheduling.config.internalAsyncExecutionAspect"
  72. BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ASYNC_EXECUTION_ASPECT_CLASS_NAME);
  73. // 使用FactoryMethod来初始化bean
  74. builder.setFactoryMethod("aspectOf");
  75. // executor属性
  76. String executor = element.getAttribute("executor");
  77. if (StringUtils.hasText(executor)) {
  78. builder.addPropertyReference("executor", executor);
  79. }
  80. // exception-handler属性
  81. String exceptionHandler = element.getAttribute("exception-handler");
  82. if (StringUtils.hasText(exceptionHandler)) {
  83. builder.addPropertyReference("exceptionHandler", exceptionHandler);
  84. }
  85. // 注册bean
  86. parserContext.registerBeanComponent(new BeanComponentDefinition(builder.getBeanDefinition(),
  87. TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME));
  88. }
  89. }
  90. }

4.2. task:executor

ExecutorBeanDefinitionParser
的主要功能是解析<task:executor/>元素,用于配置任务执行器

  1. public class ExecutorBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
  2. @Override
  3. protected String getBeanClassName(Element element) {
  4. // 使用这个类来实现bean
  5. return "org.springframework.scheduling.config.TaskExecutorFactoryBean";
  6. }
  7. @Override
  8. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  9. // keep-alive属性
  10. String keepAliveSeconds = element.getAttribute("keep-alive");
  11. if (StringUtils.hasText(keepAliveSeconds)) {
  12. builder.addPropertyValue("keepAliveSeconds", keepAliveSeconds);
  13. }
  14. // queue-capacity属性
  15. String queueCapacity = element.getAttribute("queue-capacity");
  16. if (StringUtils.hasText(queueCapacity)) {
  17. builder.addPropertyValue("queueCapacity", queueCapacity);
  18. }
  19. // 配置策略
  20. configureRejectionPolicy(element, builder);
  21. // pool-size属性
  22. String poolSize = element.getAttribute("pool-size");
  23. if (StringUtils.hasText(poolSize)) {
  24. builder.addPropertyValue("poolSize", poolSize);
  25. }
  26. }
  27. // 配置策略
  28. private void configureRejectionPolicy(Element element, BeanDefinitionBuilder builder) {
  29. // rejection-policy属性
  30. String rejectionPolicy = element.getAttribute("rejection-policy");
  31. if (!StringUtils.hasText(rejectionPolicy)) {
  32. return;
  33. }
  34. String prefix = "java.util.concurrent.ThreadPoolExecutor.";
  35. String policyClassName;
  36. if (rejectionPolicy.equals("ABORT")) {
  37. policyClassName = prefix + "AbortPolicy";
  38. }
  39. else if (rejectionPolicy.equals("CALLER_RUNS")) {
  40. policyClassName = prefix + "CallerRunsPolicy";
  41. }
  42. else if (rejectionPolicy.equals("DISCARD")) {
  43. policyClassName = prefix + "DiscardPolicy";
  44. }
  45. else if (rejectionPolicy.equals("DISCARD_OLDEST")) {
  46. policyClassName = prefix + "DiscardOldestPolicy";
  47. }
  48. else {
  49. policyClassName = rejectionPolicy;
  50. }
  51. builder.addPropertyValue("rejectedExecutionHandler", new RootBeanDefinition(policyClassName));
  52. }
  53. }

4.3. task:scheduled-tasks

ScheduledTasksBeanDefinitionParser
的主要功能是解析<task:scheduled-tasks/>元素,执行定时器任务

  1. public class ScheduledTasksBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
  2. @Override
  3. protected String getBeanClassName(Element element) {
  4. // 使用这个类来实现bean
  5. return "org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar";
  6. }
  7. @Override
  8. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  9. // cron任务
  10. ManagedList<RuntimeBeanReference> cronTaskList = new ManagedList<>();
  11. // 固定延迟任务
  12. ManagedList<RuntimeBeanReference> fixedDelayTaskList = new ManagedList<>();
  13. // 固定频率任务
  14. ManagedList<RuntimeBeanReference> fixedRateTaskList = new ManagedList<>();
  15. // 触发任务
  16. ManagedList<RuntimeBeanReference> triggerTaskList = new ManagedList<>();
  17. // 遍历子元素
  18. NodeList childNodes = element.getChildNodes();
  19. for (int i = 0; i < childNodes.getLength(); i++) {
  20. Node child = childNodes.item(i);
  21. Element taskElement = (Element) child;
  22. // ref属性
  23. String ref = taskElement.getAttribute("ref");
  24. // method属性
  25. String method = taskElement.getAttribute("method");
  26. // ... 代码省略
  27. // cron属性
  28. String cronAttribute = taskElement.getAttribute("cron");
  29. // fixed-delay属性
  30. String fixedDelayAttribute = taskElement.getAttribute("fixed-delay");
  31. // fixed-rate属性
  32. String fixedRateAttribute = taskElement.getAttribute("fixed-rate");
  33. // trigger属性
  34. String triggerAttribute = taskElement.getAttribute("trigger");
  35. // initial-delay属性
  36. String initialDelayAttribute = taskElement.getAttribute("initial-delay");
  37. boolean hasCronAttribute = StringUtils.hasText(cronAttribute);
  38. boolean hasFixedDelayAttribute = StringUtils.hasText(fixedDelayAttribute);
  39. boolean hasFixedRateAttribute = StringUtils.hasText(fixedRateAttribute);
  40. boolean hasTriggerAttribute = StringUtils.hasText(triggerAttribute);
  41. boolean hasInitialDelayAttribute = StringUtils.hasText(initialDelayAttribute);
  42. // ... 代码省略
  43. // 使用类 "org.springframework.scheduling.support.ScheduledMethodRunnable"
  44. // 实例化定时器bean
  45. String runnableName =
  46. runnableReference(ref, method, taskElement, parserContext).getBeanName();
  47. if (hasFixedDelayAttribute) {
  48. // 使用类 "org.springframework.scheduling.config.IntervalTask"
  49. // 实例化固定延迟执行器bean
  50. fixedDelayTaskList.add(intervalTaskReference(runnableName,
  51. initialDelayAttribute, fixedDelayAttribute, taskElement, parserContext));
  52. }
  53. if (hasFixedRateAttribute) {
  54. // 使用类 "org.springframework.scheduling.config.IntervalTask"
  55. // 实例化固定频率执行器bean
  56. fixedRateTaskList.add(intervalTaskReference(runnableName,
  57. initialDelayAttribute, fixedRateAttribute, taskElement, parserContext));
  58. }
  59. if (hasCronAttribute) {
  60. // 使用类 "org.springframework.scheduling.config.CronTask"
  61. // 实例化cron执行器bean
  62. cronTaskList.add(cronTaskReference(runnableName, cronAttribute,
  63. taskElement, parserContext));
  64. }
  65. if (hasTriggerAttribute) {
  66. // 使用类 "org.springframework.scheduling.config.TriggerTask"
  67. // 实例化触发执行器bean
  68. String triggerName = new RuntimeBeanReference(triggerAttribute).getBeanName();
  69. triggerTaskList.add(triggerTaskReference(runnableName, triggerName,
  70. taskElement, parserContext));
  71. }
  72. }
  73. // scheduler属性
  74. String schedulerRef = element.getAttribute("scheduler");
  75. if (StringUtils.hasText(schedulerRef)) {
  76. builder.addPropertyReference("taskScheduler", schedulerRef);
  77. }
  78. builder.addPropertyValue("cronTasksList", cronTaskList);
  79. builder.addPropertyValue("fixedDelayTasksList", fixedDelayTaskList);
  80. builder.addPropertyValue("fixedRateTasksList", fixedRateTaskList);
  81. builder.addPropertyValue("triggerTasksList", triggerTaskList);
  82. }
  83. }

4.4. task:scheduler

SchedulerBeanDefinitionParser
的主要功能是解析<task:scheduler/>元素,配置调度线程池

  1. public class SchedulerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
  2. @Override
  3. protected String getBeanClassName(Element element) {
  4. // 使用这个类来实现bean
  5. return "org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler";
  6. }
  7. @Override
  8. protected void doParse(Element element, BeanDefinitionBuilder builder) {
  9. // pool-size属性
  10. String poolSize = element.getAttribute("pool-size");
  11. if (StringUtils.hasText(poolSize)) {
  12. builder.addPropertyValue("poolSize", poolSize);
  13. }
  14. }
  15. }

5. CacheNamespaceHandler

  1. public class CacheNamespaceHandler extends NamespaceHandlerSupport {
  2. @Override
  3. public void init() {
  4. registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
  5. registerBeanDefinitionParser("advice", new CacheAdviceParser());
  6. }
  7. }

5.1. cache:annotation-driven

AnnotationDrivenCacheBeanDefinitionParser
的主要功能是解析<cache:annotation-driven/>元素,支持注解注 @Cacheable@CacheEvict@CacheUpdate

  1. class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser {
  2. @Override
  3. public BeanDefinition parse(Element element, ParserContext parserContext) {
  4. // mode属性
  5. String mode = element.getAttribute("mode");
  6. // 使用aspectj来执行
  7. if ("aspectj".equals(mode)) {
  8. registerCacheAspect(element, parserContext);
  9. }
  10. // 使用内置的功能来执行
  11. else {
  12. registerCacheAdvisor(element, parserContext);
  13. }
  14. return null;
  15. }
  16. // 使用aspectj来执行
  17. private void registerCacheAspect(Element element, ParserContext parserContext) {
  18. SpringCachingConfigurer.registerCacheAspect(element, parserContext);
  19. }
  20. // 使用内置的功能来执行
  21. private void registerCacheAdvisor(Element element, ParserContext parserContext) {
  22. AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
  23. SpringCachingConfigurer.registerCacheAdvisor(element, parserContext);
  24. }
  25. // 解析cache-resolver属性
  26. private static void parseCacheResolution(Element element, BeanDefinition def, boolean setBoth) {
  27. String name = element.getAttribute("cache-resolver");
  28. boolean hasText = StringUtils.hasText(name);
  29. if (hasText) {
  30. def.getPropertyValues().add("cacheResolver", new RuntimeBeanReference(name.trim()));
  31. }
  32. if (!hasText || setBoth) {
  33. def.getPropertyValues().add("cacheManager",
  34. new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
  35. }
  36. }
  37. }

内部类 JCacheCachingConfigurer

  1. private static class JCacheCachingConfigurer {
  2. // 使用内置的功能来执行
  3. private static void registerCacheAdvisor(Element element, ParserContext parserContext) {
  4. // bean "org.springframework.cache.config.internalJCacheAdvisor" 不存在
  5. if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME)) {
  6. Object source = parserContext.extractSource(element);
  7. // 创建一个JCache执行的bean
  8. BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, source);
  9. // 获取bean名字
  10. String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
  11. // 使用 "org.springframework.cache.jcache.interceptor.JCacheInterceptor"
  12. // 创建CacheInterceptor的bean定义
  13. RootBeanDefinition interceptorDef =
  14. new RootBeanDefinition("org.springframework.cache.jcache.interceptor.JCacheInterceptor");
  15. // ... 代码省略
  16. // 获取bean名字
  17. String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
  18. // 使用 "org.springframework.cache.jcache.interceptor.BeanFactoryJCacheOperationSourceAdvisor"
  19. // 创建CacheAdvisor定义
  20. RootBeanDefinition advisorDef = new RootBeanDefinition(
  21. "org.springframework.cache.jcache.interceptor.BeanFactoryJCacheOperationSourceAdvisor");
  22. // ... 代码省略
  23. // 注册bean "org.springframework.cache.config.internalJCacheAdvisor"
  24. parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME, advisorDef);
  25. // 注册复合bean sourceDef+interceptorDef+advisorDef
  26. CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
  27. compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
  28. compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
  29. compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME));
  30. parserContext.registerComponent(compositeDef);
  31. }
  32. }
  33. // 使用aspectj来执行
  34. private static void registerCacheAspect(Element element, ParserContext parserContext) {
  35. // bean "org.springframework.cache.config.internalJCacheAspect" 不存在
  36. if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) {
  37. Object eleSource = parserContext.extractSource(element);
  38. RootBeanDefinition def = new RootBeanDefinition();
  39. // 使用 "org.springframework.cache.aspectj.JCacheCacheAspect"
  40. // 来创建bean
  41. def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME);
  42. // 使用FactoryMethod来初始化bean
  43. def.setFactoryMethodName("aspectOf");
  44. // 创建一个JCache执行的bean
  45. BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource);
  46. String sourceName =
  47. parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
  48. // 注册bean "org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource"
  49. parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));
  50. // 注册bean "org.springframework.cache.config.internalJCacheAspect"
  51. parserContext.registerBeanComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME));
  52. }
  53. }
  54. // 创建一个JCache执行的bean
  55. private static RootBeanDefinition createJCacheOperationSourceBeanDefinition(Element element, @Nullable Object eleSource) {
  56. // 使用 "org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource""
  57. // 来创建bean
  58. RootBeanDefinition sourceDef =
  59. new RootBeanDefinition("org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource");
  60. // ... 代码省略
  61. // 解析cache-resolver属性
  62. CacheNamespaceHandler.parseKeyGenerator(element, sourceDef);
  63. return sourceDef;
  64. }
  65. }

5.2. cache:advice

CacheAdviceParser
的主要功能是解析<cache:advice/>元素,配置缓存

  1. class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
  2. @Override
  3. protected Class<?> getBeanClass(Element element) {
  4. // 使用这个类来实现bean
  5. return CacheInterceptor.class;
  6. }
  7. @Override
  8. protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
  9. // cache-manager属性
  10. builder.addPropertyReference("cacheManager", CacheNamespaceHandler.extractCacheManager(element));
  11. // caching元素
  12. List<Element> cacheDefs = DomUtils.getChildElementsByTagName(element, DEFS_ELEMENT);
  13. // 有caching元素
  14. if (!cacheDefs.isEmpty()) {
  15. // 把caching元素转化成bean
  16. List<RootBeanDefinition> attributeSourceDefinitions = parseDefinitionsSources(cacheDefs, parserContext);
  17. builder.addPropertyValue("cacheOperationSources", attributeSourceDefinitions);
  18. }
  19. else {
  20. // 没有caching元素,用 "org.springframework.cache.annotation.AnnotationCacheOperationSource"
  21. // 创建一个默认的bean
  22. builder.addPropertyValue("cacheOperationSources",
  23. new RootBeanDefinition("org.springframework.cache.annotation.AnnotationCacheOperationSource"));
  24. }
  25. }
  26. // 把caching元素转化成bean
  27. private List<RootBeanDefinition> parseDefinitionsSources(List<Element> definitions, ParserContext parserContext) {
  28. ManagedList<RootBeanDefinition> defs = new ManagedList<>(definitions.size());
  29. // 遍历
  30. for (Element element : definitions) {
  31. defs.add(parseDefinitionSource(element, parserContext));
  32. }
  33. return defs;
  34. }
  35. // 把caching元素转化成bean
  36. private RootBeanDefinition parseDefinitionSource(Element definition, ParserContext parserContext) {
  37. // ... 代码省略
  38. }
  39. }

6. MvcNamespaceHandler

  1. public class MvcNamespaceHandler extends NamespaceHandlerSupport {
  2. @Override
  3. public void init() {
  4. registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
  5. registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
  6. registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
  7. registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
  8. registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
  9. registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
  10. registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
  11. registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
  12. registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
  13. registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
  14. registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
  15. registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
  16. registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
  17. }
  18. }

mvc 命名空间的处理器内容较多,这里只解析第一个 mvc:annotation-driven,其他的有兴趣可以自行探索

AnnotationDrivenBeanDefinitionParser
的主要功能是解析<mvc:annotation-driven/>元素,启用注解驱动,通过context:component-scan标签的配置,自动扫描
@Component,@Controller,@Service,@Repository等注解标记的组件注册到工厂中,来处理请求

  1. class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
  2. @Override
  3. public BeanDefinition parse(Element element, ParserContext context) {
  4. // 元素元信息
  5. Object source = context.extractSource(element);
  6. XmlReaderContext readerContext = context.getReaderContext();
  7. // ... 代码省略
  8. // 请求映射处理器bean
  9. RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);
  10. // ... 代码省略
  11. // enable-matrix-variables属性
  12. if (element.hasAttribute("enable-matrix-variables")) {
  13. boolean enableMatrixVariables = Boolean.parseBoolean(element.getAttribute("enable-matrix-variables"));
  14. handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
  15. }
  16. // 配置路径映射
  17. configurePathMatchingProperties(handlerMappingDef, element, context);
  18. // 注册RequestMappingHandlerMapping.class bean
  19. readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
  20. // ... 代码省略
  21. // 获取数据转换服务
  22. RuntimeBeanReference conversionService = getConversionService(element, source, context);
  23. // 获取验证器
  24. RuntimeBeanReference validator = getValidator(element, source, context);
  25. // 获取文本解析器
  26. RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);
  27. // 注册ConfigurableWebBindingInitializer.class bean
  28. RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);
  29. // ... 代码省略
  30. // 载入conversionService、validator、messageCodesResolver
  31. bindingDef.getPropertyValues().add("conversionService", conversionService);
  32. bindingDef.getPropertyValues().add("validator", validator);
  33. bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);
  34. // 配置消息转换器
  35. ManagedList<?> messageConverters = getMessageConverters(element, source, context);
  36. // argument-resolvers子元素配置的自定义参数解析器
  37. ManagedList<?> argumentResolvers = getArgumentResolvers(element, context);
  38. // return-value-handlers子元素配置的自定义响应解析器
  39. ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context);
  40. // async-support子元素配置的异步任务超时时间
  41. String asyncTimeout = getAsyncTimeout(element);
  42. // async-support子元素配置的异步任务执行器
  43. RuntimeBeanReference asyncExecutor = getAsyncExecutor(element);
  44. // async-support子元素配置的callable-interceptors请求拦截器
  45. ManagedList<?> callableInterceptors = getInterceptors(element, source, context, "callable-interceptors");
  46. // async-support子元素配置的deferred-result-interceptors响应拦截器
  47. ManagedList<?> deferredResultInterceptors = getInterceptors(element, source, context, "deferred-result-interceptors");
  48. // 注册RequestMappingHandlerAdapter.class bean
  49. RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
  50. // 载入contentNegotiationManager、bindingDef、messageConverters
  51. handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
  52. handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
  53. handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
  54. // 载入jackson请求处理
  55. addRequestBodyAdvice(handlerAdapterDef);
  56. // 载入jackson响应处理
  57. addResponseBodyAdvice(handlerAdapterDef);
  58. // ignore-default-model-on-redirect属性
  59. if (element.hasAttribute("ignore-default-model-on-redirect")) {
  60. Boolean ignoreDefaultModel = Boolean.valueOf(element.getAttribute("ignore-default-model-on-redirect"));
  61. handlerAdapterDef.getPropertyValues().add("ignoreDefaultModelOnRedirect", ignoreDefaultModel);
  62. }
  63. if (argumentResolvers != null) {
  64. handlerAdapterDef.getPropertyValues().add("customArgumentResolvers", argumentResolvers);
  65. }
  66. if (returnValueHandlers != null) {
  67. handlerAdapterDef.getPropertyValues().add("customReturnValueHandlers", returnValueHandlers);
  68. }
  69. if (asyncTimeout != null) {
  70. handlerAdapterDef.getPropertyValues().add("asyncRequestTimeout", asyncTimeout);
  71. }
  72. if (asyncExecutor != null) {
  73. handlerAdapterDef.getPropertyValues().add("taskExecutor", asyncExecutor);
  74. }
  75. handlerAdapterDef.getPropertyValues().add("callableInterceptors", callableInterceptors);
  76. handlerAdapterDef.getPropertyValues().add("deferredResultInterceptors", deferredResultInterceptors);
  77. // 注册RequestMappingHandlerAdapter.class bean
  78. readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);
  79. // 注册CompositeUriComponentsContributorFactoryBean.class bean
  80. RootBeanDefinition uriContributorDef =
  81. new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class);
  82. uriContributorDef.setSource(source);
  83. uriContributorDef.getPropertyValues().addPropertyValue("handlerAdapter", handlerAdapterDef);
  84. uriContributorDef.getPropertyValues().addPropertyValue("conversionService", conversionService);
  85. // 注册mvcUriComponentsContributor bean
  86. String uriContributorName = MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME;
  87. readerContext.getRegistry().registerBeanDefinition(uriContributorName, uriContributorDef);
  88. // 注册ConversionServiceExposingInterceptor.class bean
  89. RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
  90. csInterceptorDef.setSource(source);
  91. csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);
  92. // 注册MappedInterceptor.class bean
  93. RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
  94. // ... 代码省略
  95. // 注册ExceptionHandlerExceptionResolver.class bean
  96. RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
  97. // ... 代码省略
  98. // 注册ResponseStatusExceptionResolver.class bean
  99. RootBeanDefinition statusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
  100. // ... 代码省略
  101. // 注册DefaultHandlerExceptionResolver.class bean
  102. RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
  103. // ... 代码省略
  104. // 注册一系列bean
  105. context.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
  106. context.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HANDLER_ADAPTER_BEAN_NAME));
  107. context.registerComponent(new BeanComponentDefinition(uriContributorDef, uriContributorName));
  108. context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, mappedInterceptorName));
  109. context.registerComponent(new BeanComponentDefinition(methodExceptionResolver, methodExResolverName));
  110. context.registerComponent(new BeanComponentDefinition(statusExceptionResolver, statusExResolverName));
  111. context.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExResolverName));
  112. // ... 代码省略
  113. context.popAndRegisterContainingComponent();
  114. return null;
  115. }
  116. }
  1. class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
  2. // 配置路径映射
  3. private void configurePathMatchingProperties(
  4. RootBeanDefinition handlerMappingDef, Element element, ParserContext context) {
  5. // 获取path-matching子元素
  6. Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
  7. if (pathMatchingElement != null) {
  8. Object source = context.extractSource(element);
  9. // suffix-pattern属性
  10. if (pathMatchingElement.hasAttribute("suffix-pattern")) {
  11. Boolean useSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("suffix-pattern"));
  12. handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch);
  13. }
  14. // trailing-slash属性
  15. if (pathMatchingElement.hasAttribute("trailing-slash")) {
  16. Boolean useTrailingSlashMatch = Boolean.valueOf(pathMatchingElement.getAttribute("trailing-slash"));
  17. handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch);
  18. }
  19. // registered-suffixes-only属性
  20. if (pathMatchingElement.hasAttribute("registered-suffixes-only")) {
  21. Boolean useRegisteredSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("registered-suffixes-only"));
  22. handlerMappingDef.getPropertyValues().add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch);
  23. }
  24. RuntimeBeanReference pathHelperRef = null;
  25. // path-helper属性
  26. if (pathMatchingElement.hasAttribute("path-helper")) {
  27. pathHelperRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-helper"));
  28. }
  29. pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(pathHelperRef, context, source);
  30. handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef);
  31. RuntimeBeanReference pathMatcherRef = null;
  32. // path-matcher属性
  33. if (pathMatchingElement.hasAttribute("path-matcher")) {
  34. pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher"));
  35. }
  36. pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, context, source);
  37. handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
  38. }
  39. }
  40. // 获取数据转换服务
  41. private RuntimeBeanReference getConversionService(Element element, @Nullable Object source, ParserContext context) {
  42. RuntimeBeanReference conversionServiceRef;
  43. // 有配置conversion-service属性
  44. if (element.hasAttribute("conversion-service")) {
  45. conversionServiceRef = new RuntimeBeanReference(element.getAttribute("conversion-service"));
  46. }
  47. else {
  48. // 没有就用FormattingConversionServiceFactoryBean创建一个默认的
  49. RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class);
  50. // ... 代码省略
  51. conversionServiceRef = new RuntimeBeanReference(conversionName);
  52. }
  53. return conversionServiceRef;
  54. }
  55. // 获取验证器
  56. private RuntimeBeanReference getValidator(Element element, @Nullable Object source, ParserContext context) {
  57. // 有配置validator属性
  58. if (element.hasAttribute("validator")) {
  59. return new RuntimeBeanReference(element.getAttribute("validator"));
  60. }
  61. else if (javaxValidationPresent) {
  62. // 没有就用OptionalValidatorFactoryBean创建一个默认的
  63. RootBeanDefinition validatorDef = new RootBeanDefinition(
  64. "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean");
  65. // ... 代码省略
  66. return new RuntimeBeanReference(validatorName);
  67. }
  68. else {
  69. return null;
  70. }
  71. }
  72. // 获取文本解析器
  73. private RuntimeBeanReference getMessageCodesResolver(Element element) {
  74. // 有配置message-codes-resolver属性
  75. if (element.hasAttribute("message-codes-resolver")) {
  76. return new RuntimeBeanReference(element.getAttribute("message-codes-resolver"));
  77. }
  78. else {
  79. return null;
  80. }
  81. }
  82. }
  1. class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
  2. // 配置消息转换器
  3. private ManagedList<?> getMessageConverters(Element element, @Nullable Object source, ParserContext context) {
  4. // message-converters子元素
  5. Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
  6. // 结果集
  7. ManagedList<Object> messageConverters = new ManagedList<>();
  8. // 有message-converters子元素
  9. if (convertersElement != null) {
  10. // 把bean、ref子元素转换为bean,加入结果集
  11. for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
  12. Object object = context.getDelegate().parsePropertySubElement(beanElement, null);
  13. messageConverters.add(object);
  14. }
  15. }
  16. // 有message-converters子元素,但有register-defaults属性
  17. if (convertersElement == null || Boolean.parseBoolean(convertersElement.getAttribute("register-defaults"))) {
  18. // 添加ByteArrayHttpMessageConverter.class bean到结果集
  19. // 字节数组转换器
  20. messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));
  21. // 添加StringHttpMessageConverter.class bean到结果集
  22. // 字符转换器
  23. RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
  24. stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
  25. messageConverters.add(stringConverterDef);
  26. // 添加ResourceHttpMessageConverter.class bean到结果集
  27. // 资源转换器
  28. messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
  29. // 添加ResourceRegionHttpMessageConverter.class bean到结果集
  30. // 资源区域转换器
  31. messageConverters.add(createConverterDefinition(ResourceRegionHttpMessageConverter.class, source));
  32. // 添加SourceHttpMessageConverter.class bean到结果集
  33. // javax.xml.transform.Source转换器
  34. messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
  35. // 添加AllEncompassingFormHttpMessageConverter.class bean到结果集
  36. // form-data转换器
  37. messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));
  38. // ... 代码省略
  39. if (jackson2XmlPresent) {
  40. // 添加jackson2Xml转换器
  41. }
  42. // ... 代码省略
  43. if (jackson2Present) {
  44. // 添加jackson2转换器
  45. }
  46. else if (gsonPresent) {
  47. // 添加gson转换器
  48. }
  49. // ... 代码省略
  50. }
  51. return messageConverters;
  52. }
  53. }

后续

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证

相关文章