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 许可证)