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

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

以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

20191017100144\_1.png

    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的执行过程

20191017100144\_2.png

    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) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring源码分析-配置文件加载过程

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏