上一篇:Spring5 源碼分析-容器刷新-配置類的嵌套類java
將自定義的屬性文件放到容器中environment.propertySources.propertySourceList集合中,供後面自動注入的時候使用@Value設置Bean的屬性值spring
屬性文件:框架
au.properties源碼分析
name=Messi age=30
au1.properties測試
name=HaVi age=33
au2.propertiesthis
name=武磊 age=33
配置類spa
@Configuration @ComponentScan("com.jv.spring.nestedclass.scan") @PropertySource(value = "classpath:au1.properties",name="my-au1",encoding = "utf-8") public class NestedConfig { /*@ComponentScan("com.jv.spring.nestedclass.scan") @PropertySource("classpath:au.properties") class InnerConfig{ }*/ }
測試類操作系統
public class NestedMain { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(NestedConfig.class); NestedUser bean = ac.getBean(NestedUser.class); System.out.println(bean.getName()); } }
// Process any @PropertySource annotations 處理@PropertySource註解的類 for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } else { logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } }
private void addPropertySource(PropertySource<?> propertySource) { String name = propertySource.getName(); MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources(); //若是存在同名的PropertySource,則使用CompositePropertySource替換原來的PropertySource,而CompositePropertySource中包含了全部的PropertySource if (this.propertySourceNames.contains(name)) { // We've already added a version, we need to extend it PropertySource<?> existing = propertySources.get(name); if (existing != null) { PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ? ((ResourcePropertySource) propertySource).withResourceName() : propertySource); if (existing instanceof CompositePropertySource) { //將新的PropertySource添加到第一個,使用時在該組中最後一個使用。 ((CompositePropertySource) existing).addFirstPropertySource(newSource); } else { if (existing instanceof ResourcePropertySource) { existing = ((ResourcePropertySource) existing).withResourceName(); } CompositePropertySource composite = new CompositePropertySource(name); composite.addPropertySource(newSource); composite.addPropertySource(existing); propertySources.replace(name, composite); } return; } } /** * 若是沒有同名的PropertySource,當只有一個的時候,直接添加到propertySources中 * 不然將新的PropertySource添加到除systemProperties systemEnvironment變量緊接着的第一個(意思就是後添加的後使用,可是若是他們存在同名的屬性,後使用的PropertySource會覆蓋先使用的) */ if (this.propertySourceNames.isEmpty()) { propertySources.addLast(propertySource); } else { /** * propertySourceNames中存放的是自定義的PropertySource name,不包含systemProperties systemEnvironment * 所以每次添加的新PropertySource都是在列表中的第三個(得出此結論的前提框架不在添加其餘默認的PropertySource) */ String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1); propertySources.addBefore(firstProcessed, propertySource); } this.propertySourceNames.add(name); }
@Configuration @ComponentScan("com.jv.spring.nestedclass.scan") @PropertySource(value = "classpath:au.properties",name="my-au",encoding = "utf-8") @PropertySource(value = "classpath:au1.properties",name="my-au",encoding = "utf-8") @PropertySource(value = "classpath:au2.properties",name="my-au",encoding = "utf-8") public class NestedConfig { }
DEBUG截圖.net
運行測試類輸出:3d
武磊
@Configuration @ComponentScan("com.jv.spring.nestedclass.scan") @PropertySource(value = "classpath:au.properties",name="my-au",encoding = "utf-8") @PropertySource(value = "classpath:au1.properties",name="my-au1",encoding = "utf-8") @PropertySource(value = "classpath:au2.properties",name="my-au2",encoding = "utf-8") public class NestedConfig { /*@ComponentScan("com.jv.spring.nestedclass.scan") @PropertySource("classpath:au.properties") class InnerConfig{ }*/ }
輸出內容是:
武磊
附:若是我在操做系統的環境變量中增長name=伊布,重啓Idea,運行程序輸出的結果是:
留給你們本身去思考,爲何輸出的是「伊布」,從結果反推回去能獲得一個什麼結論。
再留一個思考題:可否自定義一個PropertySource晚於systemProperties或者systemEnvironment使用,若是不能夠,那如何才能覆蓋它們兩種設置的值喃?