@PropertySource 注解提供了一种方便的声明性机制,用于将 PropertySource 添加到 Spring 的 Environment 中,与 @Configuration 类一起使用。
你可以使用 @Value 去引用定义的属性,例如:@Value("testbean.name");也可以指定默认值,如:@Value("testbean.name:defaultValue")。
给定一个包含键/值对 testbean.name=myTestBean 的文件 app.properties。以下 @Configuration 类使用 @PropertySource 将 app.properties 设置给 Environment 的 PropertySources 集合。
@Configuration @PropertySource("classpath:/com/myco/app.properties") public class AppConfig { @Autowired Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("testbean.name")); return testBean; } }
注意:使用 @Autowired 将 Environment 对象注入到配置类中,然后在 testBean() 方法中使用。 以上配置中,调用 testBean.getName() 方法将返回“myTestBean”字符串。
@PropertySource 资源中存在的任何 ${...} 占位符都将根据已在环境中注册的属性源集进行解析。例如:
@Configuration @PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties") public class AppConfig { @Autowired Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("testbean.name")); return testBean; } }
假如“my.placeholder”属性已存在于已注册的属性源之中(例如,系统属性或环境变量),则占位符将解析为相应的值。如果不是,那么将使用“默认值/路径”作为默认值。在属性后面使用冒号“:”指定默认值,例如:“my.placeholder:defaultValue”(注意:默认值是可选的)。 如果未指定默认值并且无法解析属性,则将抛出 IllegalArgumentException。
如果一个给定的属性 key 存在于多个 .properties 文件中,则最后处理的 @PropertySource 注释将覆盖前面具有相同名称的所有 key。
例如,给定两个属性文件 a.properties 和 b.properties,请考虑以下两个配置类,它们使用 @PropertySource 注解来引用它们:
@Configuration @PropertySource("classpath:/com/myco/a.properties") public class ConfigA { } @Configuration @PropertySource("classpath:/com/myco/b.properties") public class ConfigB { }
覆盖顺序取决于在应用程序上下文中注册这些类的顺序。
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(ConfigA.class); ctx.register(ConfigB.class); ctx.refresh();
在上述情况下,因为 ConfigB 是最后注册的,所以 b.properties 中的属性将覆盖 a.properties 中存在的所有重复项。
在某些情况下,使用 @PropertySource 注解严格控制属性源的顺序可能是不可行的。例如,如果上面的 @Configuration 类是通过组件扫描注册的,则顺序很难预测。在这种情况下(如果覆盖很重要),建议用户退回到使用编程式 PropertySource API。有关详细信息,请参见 ConfigurableEnvironment 和 MutablePropertySources 类的 JavaDocs 文档。
注意:根据 Java8 的约定,@PropertySource 注解可以重复。但是,所有此类 @PropertySource 注解都需要在同一级别上声明:直接在配置类上声明,或者在同一自定义注解上作为元注解声明。不建议将直接注解和元注解混合使用,因为直接注解将有效覆盖元注解。