spring源码分析-配置文件加载过程

以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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值