上一篇: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使用,若是不能够,那如何才能覆盖它们两种设置的值喃?