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

38次阅读

共计 40547 个字符,预计需要花费 102 分钟才能阅读完成。

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

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

  • SimpleConstructorNamespaceHandler
  • SimplePropertyNamespaceHandler
  • UtilNamespaceHandler
  • ContextNamespaceHandler
  • JeeNamespaceHandler
  • LangNamespaceHandler
  • TaskNamespaceHandler
  • CacheNamespaceHandler
  • MvcNamespaceHandler
  • AopNamespaceHandler
  • JdbcNamespaceHandler
  • TxNamespaceHandler

这里只解析罕用的几个

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

其余的有趣味能够自行摸索

1. SimpleConstructorNamespaceHandler

SimpleConstructorNamespaceHandler
的次要性能是在实例化如下配置的 bean

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

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

public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
    @Override
    public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {if (node instanceof Attr) {Attr attr = (Attr) node;
            // 去除两边空白
            String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
            // 去除两边空白
            String argValue = StringUtils.trimWhitespace(attr.getValue());

            // 结构函数参数汇合
            ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
            boolean ref = false;

            // 如果字段名以 "-ref" 后果,则示意在运行时对其余 bean 的援用
            if (argName.endsWith(REF_SUFFIX)) {
                ref = true;
                argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
            }

            // 用 ValueHolder 封装值
            ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
            valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));

            // 以 "_" 结尾的,示意是没有名字的参数,依照程序传入就能够了
            if (argName.startsWith(DELIMITER_PREFIX)) {String arg = argName.substring(1).trim();

                // 如果没有指定程序,间接增加
                if (!StringUtils.hasText(arg)) {cvs.addGenericArgumentValue(valueHolder);
                }
                // 如果有指定程序,指定程序增加
                else {
                    int index = -1;
                    try {index = Integer.parseInt(arg);
                    }
                    catch (NumberFormatException ex) {// ... 代码省略}

                    // ... 代码省略

                    // 增加进 cvs
                    cvs.addIndexedArgumentValue(index, valueHolder);
                }
            }
            // 有名字的参数
            else {
                // ... 代码省略

                // 增加进 cvs
                valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
                cvs.addGenericArgumentValue(valueHolder);
            }
        }
        return definition;
    }
}

2. SimplePropertyNamespaceHandler

SimplePropertyNamespaceHandler
的次要性能是在实例化如下配置的 bean

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

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

public class SimplePropertyNamespaceHandler implements NamespaceHandler {
    @Override
    public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {if (node instanceof Attr) {Attr attr = (Attr) node;
            // 属性名
            String propertyName = parserContext.getDelegate().getLocalName(attr);
            // 属性值
            String propertyValue = attr.getValue();
            // 属性汇合
            MutablePropertyValues pvs = definition.getBeanDefinition().getPropertyValues();

            // 如果字段名以 "-ref" 后果,则示意在运行时对其余 bean 的援用
            if (propertyName.endsWith(REF_SUFFIX)) {propertyName = propertyName.substring(0, propertyName.length() - REF_SUFFIX.length());
                // 把字段名从短横线 - 或下划线_式的,转化为驼峰式的
                pvs.add(Conventions.attributeNameToPropertyName(propertyName), new RuntimeBeanReference(propertyValue));
            }
            else {
                // 把字段名从短横线 - 或下划线_式的,转化为驼峰式的
                pvs.add(Conventions.attributeNameToPropertyName(propertyName), propertyValue);
            }
        }
        return definition;
    }
}

3. ContextNamespaceHandler

public class ContextNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
        registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
        registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
        registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
        registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
    }
}

3.1. context:property-placeholder

PropertyPlaceholderBeanDefinitionParser
的次要性能是解析 <context:property-placeholder/> 元素,在 bean 定义时,应用 ${} 援用内部起源的属性

先看看继承关系

- AbstractBeanDefinitionParser
  - AbstractSingleBeanDefinitionParser
    - AbstractPropertyLoadingBeanDefinitionParser
      - PropertyPlaceholderBeanDefinitionParser

3.1.1. AbstractBeanDefinitionParser

AbstractBeanDefinitionParser
的次要性能是实现了 BeanDefinitionParser
接口的 parse 办法,提供了根本的由配置解析为对象的性能

public abstract class AbstractBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public final BeanDefinition parse(Element element, ParserContext parserContext) {
        // 解析元素
        AbstractBeanDefinition definition = parseInternal(element, parserContext);

        try {
            // 获取 bean 的 id
            String id = resolveId(element, definition, parserContext);

            String[] aliases = null;
            // 获取 name 属性,用逗号分隔为多个别名
            if (shouldParseNameAsAliases()) {String name = element.getAttribute(NAME_ATTRIBUTE);
                if (StringUtils.hasLength(name)) {aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
                }
            }

            // 封装为 BeanDefinitionHolder
            BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
            // 注册到 registry 中
            registerBeanDefinition(holder, parserContext.getRegistry());

            // ... 代码省略
        }
        catch (BeanDefinitionStoreException ex) {// ... 代码省略}
        return definition;
    }

    // 解析元素,由子类实现
    protected abstract AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext);

    // 获取 bean 的 id,先获取 id 属性,其次 name 属性,都没有,生成默认的名字
    protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
            throws BeanDefinitionStoreException {// ... 代码省略}
}

3.1.2. AbstractSingleBeanDefinitionParser

AbstractSingleBeanDefinitionParser
的次要性能是反对解析为单例的 bean

public abstract class AbstractSingleBeanDefinitionParser extends AbstractBeanDefinitionParser {
    @Override
    protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
        // 创立一个结构器
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
        // 父元素
        String parentName = getParentName(element);
        if (parentName != null) {builder.getRawBeanDefinition().setParentName(parentName);
        }
        // beanClass
        Class<?> beanClass = getBeanClass(element);
        if (beanClass != null) {builder.getRawBeanDefinition().setBeanClass(beanClass);
        }
        // beanClassName
        else {String beanClassName = getBeanClassName(element);
            if (beanClassName != null) {builder.getRawBeanDefinition().setBeanClassName(beanClassName);
            }
        }

        // ... 代码省略

        // 解析到结构器
        doParse(element, parserContext, builder);
        return builder.getBeanDefinition();}

    // 解析到结构器,由子类实现
    protected void doParse(Element element, BeanDefinitionBuilder builder) {}}

3.1.3. AbstractPropertyLoadingBeanDefinitionParser

AbstractPropertyLoadingBeanDefinitionParser
的次要性能是解析 context:property-... 元素

abstract class AbstractPropertyLoadingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        // location 属性
        String location = element.getAttribute("location");
        if (StringUtils.hasLength(location)) {location = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(location);
            String[] locations = StringUtils.commaDelimitedListToStringArray(location);
            builder.addPropertyValue("locations", locations);
        }

        // properties-ref 属性
        String propertiesRef = element.getAttribute("properties-ref");
        if (StringUtils.hasLength(propertiesRef)) {builder.addPropertyReference("properties", propertiesRef);
        }

        // file-encoding 属性
        String fileEncoding = element.getAttribute("file-encoding");
        if (StringUtils.hasLength(fileEncoding)) {builder.addPropertyValue("fileEncoding", fileEncoding);
        }

        // order 属性
        String order = element.getAttribute("order");
        if (StringUtils.hasLength(order)) {builder.addPropertyValue("order", Integer.valueOf(order));
        }

        // ignore-resource-not-found 属性
        builder.addPropertyValue("ignoreResourceNotFound",
                Boolean.valueOf(element.getAttribute("ignore-resource-not-found")));

        // local-override 属性
        builder.addPropertyValue("localOverride",
                Boolean.valueOf(element.getAttribute("local-override")));
    }
}

3.1.4. PropertyPlaceholderBeanDefinitionParser

PropertyPlaceholderBeanDefinitionParser
的次要性能是解析 context:property-placeholder 元素

class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
    @Override
    protected Class<?> getBeanClass(Element element) {
        // 应用这个类来实现 bean
        return org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class;
    }

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {super.doParse(element, parserContext, builder);

        // ignore-unresolvable 属性
        builder.addPropertyValue("ignoreUnresolvablePlaceholders",
                Boolean.valueOf(element.getAttribute("ignore-unresolvable")));

        // system-properties-mode 属性
        String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE);
        if (StringUtils.hasLength(systemPropertiesModeName) &&
                !systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) {builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_" + systemPropertiesModeName);
        }

        // value-separator 属性
        if (element.hasAttribute("value-separator")) {builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
        }
        // trim-values 属性
        if (element.hasAttribute("trim-values")) {builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
        }
        // null-value 属性
        if (element.hasAttribute("null-value")) {builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
        }
    }
}

3.2. context:property-override

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

class PropertyOverrideBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
    @Override
    protected Class<?> getBeanClass(Element element) {
        // 应用这个类来实现 bean
        return PropertyOverrideConfigurer.class;
    }

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {super.doParse(element, parserContext, builder);

        // ignore-unresolvable 属性
        builder.addPropertyValue("ignoreInvalidKeys",
                Boolean.valueOf(element.getAttribute("ignore-unresolvable")));

    }
}

3.3. context:annotation-config

AnnotationConfigBeanDefinitionParser
的次要性能是解析 <context:annotation-config/> 元素,应用 @Autowired 主动拆卸 bean

public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {Object source = parserContext.extractSource(element);

        // 获取 registry 所有相干的 bean 定义
        Set<BeanDefinitionHolder> processorDefinitions =
                AnnotationConfigUtils.registerAnnotationConfigProcessors(parserContext.getRegistry(), source);

        // ... 代码省略

        // 注册 bean 定义
        for (BeanDefinitionHolder processorDefinition : processorDefinitions) {parserContext.registerComponent(new BeanComponentDefinition(processorDefinition));
        }

        // ... 代码省略

        return null;
    }
}

3.4. context:component-scan

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

public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        // base-package 属性
        String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
        basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
        // 分隔多个包
        String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
                ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

        // 创立并配置扫描对象
        ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
        // 扫描包中的组件
        Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
        // 注册组件到上下文中
        registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

        return null;
    }
}

对于 context: 命令空间的解析就到这里了,其余的有趣味能够自行摸索

4. TaskNamespaceHandler

public class TaskNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {this.registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        this.registerBeanDefinitionParser("executor", new ExecutorBeanDefinitionParser());
        this.registerBeanDefinitionParser("scheduled-tasks", new ScheduledTasksBeanDefinitionParser());
        this.registerBeanDefinitionParser("scheduler", new SchedulerBeanDefinitionParser());
    }
}

4.1. task:annotation-driven

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

public class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {Object source = parserContext.extractSource(element);

        // ... 代码省略

        // 获取 registry
        BeanDefinitionRegistry registry = parserContext.getRegistry();

        // mode 属性
        String mode = element.getAttribute("mode");
        // 应用 aspectj 来执行异步工作
        if ("aspectj".equals(mode)) {
            // mode="aspectj"
            registerAsyncExecutionAspect(element, parserContext);
        }
        // 应用内置的性能来执行异步工作
        else {
            // bean "org.springframework.context.annotation.internalAsyncAnnotationProcessor" 曾经存在
            if (registry.containsBeanDefinition(TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)) {// ... 代码省略}
            else {
                // 应用类 "org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor"
                // 来配置 bean "org.springframework.context.annotation.internalAsyncAnnotationProcessor"
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor");
                builder.getRawBeanDefinition().setSource(source);
                // executor 属性
                String executor = element.getAttribute("executor");
                if (StringUtils.hasText(executor)) {builder.addPropertyReference("executor", executor);
                }
                // exception-handler 属性
                String exceptionHandler = element.getAttribute("exception-handler");
                if (StringUtils.hasText(exceptionHandler)) {builder.addPropertyReference("exceptionHandler", exceptionHandler);
                }
                // proxy-target-class 属性
                if (Boolean.parseBoolean(element.getAttribute(AopNamespaceUtils.PROXY_TARGET_CLASS_ATTRIBUTE))) {builder.addPropertyValue("proxyTargetClass", true);
                }
                // 注册组件到 registry 与上下文
                registerPostProcessor(parserContext, builder, TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME);
            }
        }

        // bean "org.springframework.context.annotation.internalScheduledAnnotationProcessor" 曾经存在
        if (registry.containsBeanDefinition(TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)) {// ... 代码省略}
        else {
            // 应用类 "org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor"
            // 来配置 bean "org.springframework.context.annotation.internalScheduledAnnotationProcessor"
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition("org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor");
            builder.getRawBeanDefinition().setSource(source);
            // scheduler 属性
            String scheduler = element.getAttribute("scheduler");
            if (StringUtils.hasText(scheduler)) {builder.addPropertyReference("scheduler", scheduler);
            }
            // 注册组件到 registry 与上下文
            registerPostProcessor(parserContext, builder, TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME);
        }

        // ... 代码省略

        return null;
    }

    // 应用 aspectj 来执行异步工作
    private void registerAsyncExecutionAspect(Element element, ParserContext parserContext) {
        // bean "org.springframework.scheduling.config.internalAsyncExecutionAspect" 不存在
        if (!parserContext.getRegistry().containsBeanDefinition(TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)) {
            // 应用类 "org.springframework.scheduling.aspectj.AnnotationAsyncExecutionAspect"
            // 来配置 bean "org.springframework.scheduling.config.internalAsyncExecutionAspect"
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ASYNC_EXECUTION_ASPECT_CLASS_NAME);
            // 应用 FactoryMethod 来初始化 bean
            builder.setFactoryMethod("aspectOf");
            // executor 属性
            String executor = element.getAttribute("executor");
            if (StringUtils.hasText(executor)) {builder.addPropertyReference("executor", executor);
            }
            // exception-handler 属性
            String exceptionHandler = element.getAttribute("exception-handler");
            if (StringUtils.hasText(exceptionHandler)) {builder.addPropertyReference("exceptionHandler", exceptionHandler);
            }
            // 注册 bean
            parserContext.registerBeanComponent(new BeanComponentDefinition(builder.getBeanDefinition(),
                    TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME));
        }
    }
}

4.2. task:executor

ExecutorBeanDefinitionParser
的次要性能是解析 <task:executor/> 元素,用于配置工作执行器

public class ExecutorBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected String getBeanClassName(Element element) {
        // 应用这个类来实现 bean
        return "org.springframework.scheduling.config.TaskExecutorFactoryBean";
    }

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        // keep-alive 属性
        String keepAliveSeconds = element.getAttribute("keep-alive");
        if (StringUtils.hasText(keepAliveSeconds)) {builder.addPropertyValue("keepAliveSeconds", keepAliveSeconds);
        }
        // queue-capacity 属性
        String queueCapacity = element.getAttribute("queue-capacity");
        if (StringUtils.hasText(queueCapacity)) {builder.addPropertyValue("queueCapacity", queueCapacity);
        }
        // 配置策略
        configureRejectionPolicy(element, builder);
        // pool-size 属性
        String poolSize = element.getAttribute("pool-size");
        if (StringUtils.hasText(poolSize)) {builder.addPropertyValue("poolSize", poolSize);
        }
    }

    // 配置策略
    private void configureRejectionPolicy(Element element, BeanDefinitionBuilder builder) {
        // rejection-policy 属性
        String rejectionPolicy = element.getAttribute("rejection-policy");
        if (!StringUtils.hasText(rejectionPolicy)) {return;}
        String prefix = "java.util.concurrent.ThreadPoolExecutor.";
        String policyClassName;
        if (rejectionPolicy.equals("ABORT")) {policyClassName = prefix + "AbortPolicy";}
        else if (rejectionPolicy.equals("CALLER_RUNS")) {policyClassName = prefix + "CallerRunsPolicy";}
        else if (rejectionPolicy.equals("DISCARD")) {policyClassName = prefix + "DiscardPolicy";}
        else if (rejectionPolicy.equals("DISCARD_OLDEST")) {policyClassName = prefix + "DiscardOldestPolicy";}
        else {policyClassName = rejectionPolicy;}
        builder.addPropertyValue("rejectedExecutionHandler", new RootBeanDefinition(policyClassName));
    }

}

4.3. task:scheduled-tasks

ScheduledTasksBeanDefinitionParser
的次要性能是解析 <task:scheduled-tasks/> 元素,执行定时器工作

public class ScheduledTasksBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected String getBeanClassName(Element element) {
        // 应用这个类来实现 bean
        return "org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar";
    }

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        // cron 工作
        ManagedList<RuntimeBeanReference> cronTaskList = new ManagedList<>();
        // 固定提早工作
        ManagedList<RuntimeBeanReference> fixedDelayTaskList = new ManagedList<>();
        // 固定频率工作
        ManagedList<RuntimeBeanReference> fixedRateTaskList = new ManagedList<>();
        // 触发工作
        ManagedList<RuntimeBeanReference> triggerTaskList = new ManagedList<>();

        // 遍历子元素
        NodeList childNodes = element.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {Node child = childNodes.item(i);

            Element taskElement = (Element) child;
            // ref 属性
            String ref = taskElement.getAttribute("ref");
            // method 属性
            String method = taskElement.getAttribute("method");

            // ... 代码省略

            // cron 属性
            String cronAttribute = taskElement.getAttribute("cron");
            // fixed-delay 属性
            String fixedDelayAttribute = taskElement.getAttribute("fixed-delay");
            // fixed-rate 属性
            String fixedRateAttribute = taskElement.getAttribute("fixed-rate");
            // trigger 属性
            String triggerAttribute = taskElement.getAttribute("trigger");
            // initial-delay 属性
            String initialDelayAttribute = taskElement.getAttribute("initial-delay");

            boolean hasCronAttribute = StringUtils.hasText(cronAttribute);
            boolean hasFixedDelayAttribute = StringUtils.hasText(fixedDelayAttribute);
            boolean hasFixedRateAttribute = StringUtils.hasText(fixedRateAttribute);
            boolean hasTriggerAttribute = StringUtils.hasText(triggerAttribute);
            boolean hasInitialDelayAttribute = StringUtils.hasText(initialDelayAttribute);

            // ... 代码省略

            // 应用类 "org.springframework.scheduling.support.ScheduledMethodRunnable"
            // 实例化定时器 bean
            String runnableName =
                    runnableReference(ref, method, taskElement, parserContext).getBeanName();

            if (hasFixedDelayAttribute) {
                // 应用类 "org.springframework.scheduling.config.IntervalTask"
                // 实例化固定提早执行器 bean
                fixedDelayTaskList.add(intervalTaskReference(runnableName,
                        initialDelayAttribute, fixedDelayAttribute, taskElement, parserContext));
            }
            if (hasFixedRateAttribute) {
                // 应用类 "org.springframework.scheduling.config.IntervalTask"
                // 实例化固定频率执行器 bean
                fixedRateTaskList.add(intervalTaskReference(runnableName,
                        initialDelayAttribute, fixedRateAttribute, taskElement, parserContext));
            }
            if (hasCronAttribute) {
                // 应用类 "org.springframework.scheduling.config.CronTask"
                // 实例化 cron 执行器 bean
                cronTaskList.add(cronTaskReference(runnableName, cronAttribute,
                        taskElement, parserContext));
            }
            if (hasTriggerAttribute) {
                // 应用类 "org.springframework.scheduling.config.TriggerTask"
                // 实例化触发执行器 bean
                String triggerName = new RuntimeBeanReference(triggerAttribute).getBeanName();
                triggerTaskList.add(triggerTaskReference(runnableName, triggerName,
                        taskElement, parserContext));
            }
        }
        // scheduler 属性
        String schedulerRef = element.getAttribute("scheduler");
        if (StringUtils.hasText(schedulerRef)) {builder.addPropertyReference("taskScheduler", schedulerRef);
        }
        builder.addPropertyValue("cronTasksList", cronTaskList);
        builder.addPropertyValue("fixedDelayTasksList", fixedDelayTaskList);
        builder.addPropertyValue("fixedRateTasksList", fixedRateTaskList);
        builder.addPropertyValue("triggerTasksList", triggerTaskList);
    }
}

4.4. task:scheduler

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

public class SchedulerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected String getBeanClassName(Element element) {
        // 应用这个类来实现 bean
        return "org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler";
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
        // pool-size 属性
        String poolSize = element.getAttribute("pool-size");
        if (StringUtils.hasText(poolSize)) {builder.addPropertyValue("poolSize", poolSize);
        }
    }
}

5. CacheNamespaceHandler

public class CacheNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
        registerBeanDefinitionParser("advice", new CacheAdviceParser());
    }
}

5.1. cache:annotation-driven

AnnotationDrivenCacheBeanDefinitionParser
的次要性能是解析 <cache:annotation-driven/> 元素,反对注解注 @Cacheable@CacheEvict@CacheUpdate

class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        // mode 属性
        String mode = element.getAttribute("mode");
        // 应用 aspectj 来执行
        if ("aspectj".equals(mode)) {registerCacheAspect(element, parserContext);
        }
        // 应用内置的性能来执行
        else {registerCacheAdvisor(element, parserContext);
        }

        return null;
    }

    // 应用 aspectj 来执行
    private void registerCacheAspect(Element element, ParserContext parserContext) {SpringCachingConfigurer.registerCacheAspect(element, parserContext);
    }

    // 应用内置的性能来执行
    private void registerCacheAdvisor(Element element, ParserContext parserContext) {AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
        SpringCachingConfigurer.registerCacheAdvisor(element, parserContext);
    }

    // 解析 cache-resolver 属性
    private static void parseCacheResolution(Element element, BeanDefinition def, boolean setBoth) {String name = element.getAttribute("cache-resolver");
        boolean hasText = StringUtils.hasText(name);
        if (hasText) {def.getPropertyValues().add("cacheResolver", new RuntimeBeanReference(name.trim()));
        }
        if (!hasText || setBoth) {def.getPropertyValues().add("cacheManager",
                    new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
        }
    }
}

外部类 JCacheCachingConfigurer

private static class JCacheCachingConfigurer {
    // 应用内置的性能来执行
    private static void registerCacheAdvisor(Element element, ParserContext parserContext) {
        // bean "org.springframework.cache.config.internalJCacheAdvisor" 不存在
        if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME)) {Object source = parserContext.extractSource(element);

            // 创立一个 JCache 执行的 bean
            BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, source);
            // 获取 bean 名字
            String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

            // 应用 "org.springframework.cache.jcache.interceptor.JCacheInterceptor"
            // 创立 CacheInterceptor 的 bean 定义
            RootBeanDefinition interceptorDef =
                    new RootBeanDefinition("org.springframework.cache.jcache.interceptor.JCacheInterceptor");

            // ... 代码省略

            // 获取 bean 名字
            String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

            // 应用 "org.springframework.cache.jcache.interceptor.BeanFactoryJCacheOperationSourceAdvisor"
            // 创立 CacheAdvisor 定义
            RootBeanDefinition advisorDef = new RootBeanDefinition("org.springframework.cache.jcache.interceptor.BeanFactoryJCacheOperationSourceAdvisor");

            // ... 代码省略

            // 注册 bean "org.springframework.cache.config.internalJCacheAdvisor"
            parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME, advisorDef);

            // 注册复合 bean sourceDef+interceptorDef+advisorDef
            CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
            compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
            compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
            compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME));
            parserContext.registerComponent(compositeDef);
        }
    }

    // 应用 aspectj 来执行
    private static void registerCacheAspect(Element element, ParserContext parserContext) {
        // bean "org.springframework.cache.config.internalJCacheAspect" 不存在
        if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME)) {Object eleSource = parserContext.extractSource(element);
            RootBeanDefinition def = new RootBeanDefinition();

            // 应用 "org.springframework.cache.aspectj.JCacheCacheAspect"
            // 来创立 bean
            def.setBeanClassName(JCACHE_ASPECT_CLASS_NAME);
            // 应用 FactoryMethod 来初始化 bean
            def.setFactoryMethodName("aspectOf");
            // 创立一个 JCache 执行的 bean
            BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource);
            String sourceName =
                    parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

            // 注册 bean "org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource"
            parserContext.registerBeanComponent(new BeanComponentDefinition(sourceDef, sourceName));
            // 注册 bean "org.springframework.cache.config.internalJCacheAspect"
            parserContext.registerBeanComponent(new BeanComponentDefinition(def, CacheManagementConfigUtils.JCACHE_ASPECT_BEAN_NAME));
        }
    }

    // 创立一个 JCache 执行的 bean
    private static RootBeanDefinition createJCacheOperationSourceBeanDefinition(Element element, @Nullable Object eleSource) {
        // 应用 "org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource""
        // 来创立 bean
        RootBeanDefinition sourceDef =
                new RootBeanDefinition("org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource");

        // ... 代码省略

        // 解析 cache-resolver 属性
        CacheNamespaceHandler.parseKeyGenerator(element, sourceDef);
        return sourceDef;
    }
}

5.2. cache:advice

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

class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected Class<?> getBeanClass(Element element) {
        // 应用这个类来实现 bean
        return CacheInterceptor.class;
    }

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        // cache-manager 属性
        builder.addPropertyReference("cacheManager", CacheNamespaceHandler.extractCacheManager(element));

        // caching 元素
        List<Element> cacheDefs = DomUtils.getChildElementsByTagName(element, DEFS_ELEMENT);
        // 有 caching 元素
        if (!cacheDefs.isEmpty()) {
            // 把 caching 元素转化成 bean
            List<RootBeanDefinition> attributeSourceDefinitions = parseDefinitionsSources(cacheDefs, parserContext);
            builder.addPropertyValue("cacheOperationSources", attributeSourceDefinitions);
        }
        else {
            // 没有 caching 元素,用 "org.springframework.cache.annotation.AnnotationCacheOperationSource"
            // 创立一个默认的 bean
            builder.addPropertyValue("cacheOperationSources",
                    new RootBeanDefinition("org.springframework.cache.annotation.AnnotationCacheOperationSource"));
        }
    }

    // 把 caching 元素转化成 bean
    private List<RootBeanDefinition> parseDefinitionsSources(List<Element> definitions, ParserContext parserContext) {ManagedList<RootBeanDefinition> defs = new ManagedList<>(definitions.size());

        // 遍历
        for (Element element : definitions) {defs.add(parseDefinitionSource(element, parserContext));
        }

        return defs;
    }

    // 把 caching 元素转化成 bean
    private RootBeanDefinition parseDefinitionSource(Element definition, ParserContext parserContext) {// ... 代码省略}
}

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

mvc 命名空间的处理器内容较多,这里只解析第一个 mvc:annotation-driven,其余的有趣味能够自行摸索

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

class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext context) {
        // 元素元信息
        Object source = context.extractSource(element);
        XmlReaderContext readerContext = context.getReaderContext();

        // ... 代码省略

        // 申请映射处理器 bean
        RootBeanDefinition handlerMappingDef = new RootBeanDefinition(RequestMappingHandlerMapping.class);

        // ... 代码省略

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

        // 配置门路映射
        configurePathMatchingProperties(handlerMappingDef, element, context);
        // 注册 RequestMappingHandlerMapping.class bean
        readerContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);

        // ... 代码省略

        // 获取数据转换服务
        RuntimeBeanReference conversionService = getConversionService(element, source, context);
        // 获取验证器
        RuntimeBeanReference validator = getValidator(element, source, context);
        // 获取文本解析器
        RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);

        // 注册 ConfigurableWebBindingInitializer.class bean
        RootBeanDefinition bindingDef = new RootBeanDefinition(ConfigurableWebBindingInitializer.class);

        // ... 代码省略

        // 载入 conversionService、validator、messageCodesResolver
        bindingDef.getPropertyValues().add("conversionService", conversionService);
        bindingDef.getPropertyValues().add("validator", validator);
        bindingDef.getPropertyValues().add("messageCodesResolver", messageCodesResolver);

        // 配置音讯转换器
        ManagedList<?> messageConverters = getMessageConverters(element, source, context);
        // argument-resolvers 子元素配置的自定义参数解析器
        ManagedList<?> argumentResolvers = getArgumentResolvers(element, context);
        // return-value-handlers 子元素配置的自定义响应解析器
        ManagedList<?> returnValueHandlers = getReturnValueHandlers(element, context);
        // async-support 子元素配置的异步工作超时工夫
        String asyncTimeout = getAsyncTimeout(element);
        // async-support 子元素配置的异步工作执行器
        RuntimeBeanReference asyncExecutor = getAsyncExecutor(element);
        // async-support 子元素配置的 callable-interceptors 申请拦截器
        ManagedList<?> callableInterceptors = getInterceptors(element, source, context, "callable-interceptors");
        // async-support 子元素配置的 deferred-result-interceptors 响应拦截器
        ManagedList<?> deferredResultInterceptors = getInterceptors(element, source, context, "deferred-result-interceptors");

        // 注册 RequestMappingHandlerAdapter.class bean
        RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(RequestMappingHandlerAdapter.class);
        // 载入 contentNegotiationManager、bindingDef、messageConverters
        handlerAdapterDef.getPropertyValues().add("contentNegotiationManager", contentNegotiationManager);
        handlerAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
        handlerAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
        // 载入 jackson 申请解决
        addRequestBodyAdvice(handlerAdapterDef);
        // 载入 jackson 响应解决
        addResponseBodyAdvice(handlerAdapterDef);

        // ignore-default-model-on-redirect 属性
        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);

        // 注册 RequestMappingHandlerAdapter.class bean
        readerContext.getRegistry().registerBeanDefinition(HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef);

        // 注册 CompositeUriComponentsContributorFactoryBean.class bean
        RootBeanDefinition uriContributorDef =
                new RootBeanDefinition(CompositeUriComponentsContributorFactoryBean.class);
        uriContributorDef.setSource(source);
        uriContributorDef.getPropertyValues().addPropertyValue("handlerAdapter", handlerAdapterDef);
        uriContributorDef.getPropertyValues().addPropertyValue("conversionService", conversionService);

        // 注册 mvcUriComponentsContributor bean
        String uriContributorName = MvcUriComponentsBuilder.MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME;
        readerContext.getRegistry().registerBeanDefinition(uriContributorName, uriContributorDef);

        // 注册 ConversionServiceExposingInterceptor.class bean
        RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
        csInterceptorDef.setSource(source);
        csInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, conversionService);

        // 注册 MappedInterceptor.class bean
        RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);

        // ... 代码省略

        // 注册 ExceptionHandlerExceptionResolver.class bean
        RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);

        // ... 代码省略

        // 注册 ResponseStatusExceptionResolver.class bean
        RootBeanDefinition statusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);

        // ... 代码省略

        // 注册 DefaultHandlerExceptionResolver.class bean
        RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);

        // ... 代码省略

        // 注册一系列 bean
        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));

        // ... 代码省略

        context.popAndRegisterContainingComponent();

        return null;
    }
}
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
    // 配置门路映射
    private void configurePathMatchingProperties(RootBeanDefinition handlerMappingDef, Element element, ParserContext context) {
        // 获取 path-matching 子元素
        Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
        if (pathMatchingElement != null) {Object source = context.extractSource(element);

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

            RuntimeBeanReference pathHelperRef = null;
            // path-helper 属性
            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;
            // path-matcher 属性
            if (pathMatchingElement.hasAttribute("path-matcher")) {pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher"));
            }
            pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, context, source);
            handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
        }
    }

    // 获取数据转换服务
    private RuntimeBeanReference getConversionService(Element element, @Nullable Object source, ParserContext context) {
        RuntimeBeanReference conversionServiceRef;
        // 有配置 conversion-service 属性
        if (element.hasAttribute("conversion-service")) {conversionServiceRef = new RuntimeBeanReference(element.getAttribute("conversion-service"));
        }
        else {
            // 没有就用 FormattingConversionServiceFactoryBean 创立一个默认的
            RootBeanDefinition conversionDef = new RootBeanDefinition(FormattingConversionServiceFactoryBean.class);

            // ... 代码省略

            conversionServiceRef = new RuntimeBeanReference(conversionName);
        }
        return conversionServiceRef;
    }

    // 获取验证器
    private RuntimeBeanReference getValidator(Element element, @Nullable Object source, ParserContext context) {
        // 有配置 validator 属性
        if (element.hasAttribute("validator")) {return new RuntimeBeanReference(element.getAttribute("validator"));
        }
        else if (javaxValidationPresent) {
            // 没有就用 OptionalValidatorFactoryBean 创立一个默认的
            RootBeanDefinition validatorDef = new RootBeanDefinition("org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean");

            // ... 代码省略

            return new RuntimeBeanReference(validatorName);
        }
        else {return null;}
    }

    // 获取文本解析器
    private RuntimeBeanReference getMessageCodesResolver(Element element) {
        // 有配置 message-codes-resolver 属性
        if (element.hasAttribute("message-codes-resolver")) {return new RuntimeBeanReference(element.getAttribute("message-codes-resolver"));
        }
        else {return null;}
    }
}
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
    // 配置音讯转换器
    private ManagedList<?> getMessageConverters(Element element, @Nullable Object source, ParserContext context) {
        // message-converters 子元素
        Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
        // 后果集
        ManagedList<Object> messageConverters = new ManagedList<>();

        // 有 message-converters 子元素
        if (convertersElement != null) {
            // 把 bean、ref 子元素转换为 bean,退出后果集
            for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {Object object = context.getDelegate().parsePropertySubElement(beanElement, null);
                messageConverters.add(object);
            }
        }

        // 有 message-converters 子元素,但有 register-defaults 属性
        if (convertersElement == null || Boolean.parseBoolean(convertersElement.getAttribute("register-defaults"))) {
            // 增加 ByteArrayHttpMessageConverter.class bean 到后果集
            // 字节数组转换器
            messageConverters.add(createConverterDefinition(ByteArrayHttpMessageConverter.class, source));

            // 增加 StringHttpMessageConverter.class bean 到后果集
            // 字符转换器
            RootBeanDefinition stringConverterDef = createConverterDefinition(StringHttpMessageConverter.class, source);
            stringConverterDef.getPropertyValues().add("writeAcceptCharset", false);
            messageConverters.add(stringConverterDef);

            // 增加 ResourceHttpMessageConverter.class bean 到后果集
            // 资源转换器
            messageConverters.add(createConverterDefinition(ResourceHttpMessageConverter.class, source));
            // 增加 ResourceRegionHttpMessageConverter.class bean 到后果集
            // 资源区域转换器
            messageConverters.add(createConverterDefinition(ResourceRegionHttpMessageConverter.class, source));
            // 增加 SourceHttpMessageConverter.class bean 到后果集
            // javax.xml.transform.Source 转换器
            messageConverters.add(createConverterDefinition(SourceHttpMessageConverter.class, source));
            // 增加 AllEncompassingFormHttpMessageConverter.class bean 到后果集
            // form-data 转换器
            messageConverters.add(createConverterDefinition(AllEncompassingFormHttpMessageConverter.class, source));

            // ... 代码省略

            if (jackson2XmlPresent) {// 增加 jackson2Xml 转换器}

            // ... 代码省略

            if (jackson2Present) {// 增加 jackson2 转换器}
            else if (gsonPresent) {// 增加 gson 转换器}

            // ... 代码省略
        }
        return messageConverters;
    }
}

后续

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

作者:深予之 (@senntyou)

版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)

正文完
 0