spring源码分析-配置文件加载过程
来源:互联网 发布:提升关键词排名软件 编辑:程序博客网 时间:2024/06/04 18:34
以property-placeholder为例
(1)看spring如何读取xml配置文件中的标签
(2) 加载properties文件的过程
入口:
AbstractApplicationContext的refresh()中的
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
这个方法生成BeanFactory,解析xml文件,生成BeanDifinition,注册到beanFactory中
看下具体流程
首先在refreshBeanFactory()
this.loadBeanDefinitions(ex);
然后DefaultBeanDefinitionDocumentReader中
this.parseBeanDefinitions(root, this.delegate);然后DefaultBeanDefinitionDocumentReader处理每一个xml中到每一个元素delegate.parseCustomElement(ele);
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { String namespaceUri = this.getNamespaceURI(ele); NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if(handler == null) { this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } else { return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }}首先通过元素获取NamespaceUri,进而获取对应的namespaceHandler,然后获取对应的BeanDifinitionParser最后到AbstractBeanDefinitionParser
public final BeanDefinition parse(Element element, ParserContext parserContext) { AbstractBeanDefinition definition = this.parseInternal(element, parserContext); if(definition != null && !parserContext.isNested()) { try { String ex = this.resolveId(element, definition, parserContext); if(!StringUtils.hasText(ex)) { parserContext.getReaderContext().error("Id is required for element \'" + parserContext.getDelegate().getLocalName(element) + "\' when used as a top-level tag", element); } String[] aliases = null; if(this.shouldParseNameAsAliases()) { String holder = element.getAttribute("name"); if(StringUtils.hasLength(holder)) { aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(holder)); } } BeanDefinitionHolder holder1 = new BeanDefinitionHolder(definition, ex, aliases); this.registerBeanDefinition(holder1, parserContext.getRegistry()); if(this.shouldFireEvents()) { BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder1); this.postProcessComponentDefinition(componentDefinition); parserContext.registerComponent(componentDefinition); } } catch (BeanDefinitionStoreException var8) { parserContext.getReaderContext().error(var8.getMessage(), element); return null; } } return definition;}此时 改元素形成了对应的BeanDifinition,注册到Beanfactory中。我们看下<context:property-placeholder location="classpath:trade-config.properties" order="1" ignore-unresolvable="true"/>这个元素生成的 BeanDifinition
PropertySourcesPlaceholderConfigurers
是一个BeanFactoryPostProcessor这类的bean会在下面这个方法初始化和执行对应的方法
AbstractApplicationContext
this.invokeBeanFactoryPostProcessors(beanFactory);
在下面的代码中
String[] var15 = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);ArrayList var16 = new ArrayList();ArrayList var17 = new ArrayList();ArrayList var19 = new ArrayList();String[] var21 = var15;int var24 = var15.length;String var29;for(postProcessorName = 0; postProcessorName < var24; ++postProcessorName) { var29 = var21[postProcessorName]; if(!processedBeans.contains(var29)) { if(beanFactory.isTypeMatch(var29, PriorityOrdered.class)) { var16.add(beanFactory.getBean(var29, BeanFactoryPostProcessor.class)); } else if(beanFactory.isTypeMatch(var29, Ordered.class)) { var17.add(var29); } else { var19.add(var29); } }}OrderComparator.sort(var16);invokeBeanFactoryPostProcessors((Collection)var16, (ConfigurableListableBeanFactory)beanFactory);
从BeanFactory中拿到BeanFactoryPostProcessor类型的bean
执行其postProcessBeanFactory()
我们来看下下面这个bean的执行过程
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if(this.propertySources == null) { this.propertySources = new MutablePropertySources(); if(this.environment != null) { this.propertySources.addLast(new PropertySource("environmentProperties", this.environment) { public String getProperty(String key) { return ((Environment)this.source).getProperty(key); } }); } try {
//从location读取properties文件,存在ex中,这里是读properties文件的地方!! PropertiesPropertySource ex = new PropertiesPropertySource("localProperties", this.mergeProperties()); if(this.localOverride) { this.propertySources.addFirst(ex); } else { this.propertySources.addLast(ex); } } catch (IOException var3) { throw new BeanInitializationException("Could not load properties", var3); } } //生成resolver,放到BeanFactory
this.processProperties(beanFactory, (ConfigurablePropertyResolver)(new PropertySourcesPropertyResolver(this.propertySources)));
this.appliedPropertySources = this.propertySources;}
接着进入PlaceholderConfigurerSupport
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, StringValueResolver valueResolver) { BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver); String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames(); String[] var5 = beanNames; int var6 = beanNames.length; for(int var7 = 0; var7 < var6; ++var7) { String curName = var5[var7]; if(!curName.equals(this.beanName) || !beanFactoryToProcess.equals(this.beanFactory)) { BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName); try { visitor.visitBeanDefinition(bd); } catch (Exception var11) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, var11.getMessage(), var11); } } } beanFactoryToProcess.resolveAliases(valueResolver); beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);}
现在我们看下在
@Value("${feature.enableCreditAssign}")boolean enableCreditAssign;
我们看下这个变量的注入过程
进入AbstractBeanFactory
public String resolveEmbeddedValue(String value) { String result = value; StringValueResolver resolver; for(Iterator var3 = this.embeddedValueResolvers.iterator(); var3.hasNext(); result = resolver.resolveStringValue(result)) { resolver = (StringValueResolver)var3.next(); if(result == null) { return null; } } return result;}
阅读全文
0 0
- spring源码分析-配置文件加载过程
- hibernate源码-配置文件加载过程分析
- spring源码分析 加载bean过程
- 【Spring】从源码分析Spring配置文件的加载
- Spring源码分析:Bean加载流程概览及配置文件读取
- Spring 源码分析:Bean 加载流程概览及配置文件读取
- Spring源码分析之配置文件加载并注册Bean
- Spring IOC 源码分析-xml配置文件加载-注册
- Spring 源码分析:Spring容器的加载过程
- spring启动component-scan类扫描加载过程---源码分析
- spring启动component-scan类扫描加载过程---源码分析
- spring启动component-scan类扫描加载过程---源码分析
- spring启动component-scan类扫描加载过程---源码分析
- spring启动component-scan类扫描加载过程---源码分析
- 【spring源码分析】加载bean过程(1)
- 【spring源码分析】加载bean过程(2)
- Spring加载过程源码解读
- mybatis源码学习之执行过程分析(0)——配置文件加载(io包)
- 正则表达式30分钟入门教程
- 梯度下降法与反向传播
- hdu 2830 Matrix Swapping II
- Oracle:数据库对象(二)
- 后端接口的幂等性
- spring源码分析-配置文件加载过程
- 数据库SQL的安全性控制
- redis学习(六)——Sorted Set数据类型
- 记录使用svn的过程
- 死锁
- 海量数据面试题整理
- [jzoj5462]【NOIP2017提高A组冲刺11.8】好文章
- 软件工程(C编码实践篇)学习总结
- 【期望DP】HDU4405 Aeroplane chess