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