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;}




原创粉丝点击