给定以下简单的spring启动示例应用程序:
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
和
@PropertySource(value="classpath:properties/tables/adres.properties")
@PropertySource(value="classpath:properties/tables/person.properties")
@Component
public class Sample {
@Value("${table.name}")
private String tableName;
@Value("${table.columns}")
private String[] columns;
@Value("${table.data.types}")
private String[] dataTypes;
@PostConstruct
public void init() {
// do something with values from properties...
for (String column : columns) {
System.out.println(column);
}
}
}
以及以下示例属性:
adres.properties:
table.name=adres
table.columns=personId,streetName,cityName
table.data.types=integer,string,string
person.properties:
table.name=person
table.columns=personId,firstName,lastName
table.data.types=integer,string,string
我想
@PropertySource
我尝试了以下内容:
1
使用通配符*
从目录(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html#resources-classpath-wildcards)获取所有属性,如下所示:
@PropertySource(value="classpath*:properties/tables/*.properties")
抛出java.io.FileNotFoundException: class path resource [properties/tables/*.properties] cannot be opened because it does not exist
,所以看起来它将*
解析为文字值而不是通配符。
按照How to read multiple properties having the same keys in Spring?:
中的建议将PropertySourcesPlaceholderConfigurer
添加到Application类
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer config = new PropertySourcesPlaceholderConfigurer();
config.setIgnoreUnresolvablePlaceholders(true);
return config;
}
似乎无法正常工作,因为java.io.FileNotFoundException
在加载PropertySourcesPlaceholderConfigurer
之前被抛出。
2
重新获取值也很困难,因为每个属性都使用相同的键。这样做是为了保证属性文件的一致性和可维护性。我尝试通过使用更多占位符来解决这个问题:
table.name=person
{table.name}.columns=personId,firstName,lastName
{table.name}.data.types=integer,string,string
和Sample.class
@Value("${table.name}")
private String tableName;
@Value("${{table.name}.columns}")
private String[] columns;
@Value("${{table.name}.data.types}")
private String[] dataTypes;
占位符有效,但我仍然需要手动添加所有@PropertySource
,并且只能从最后加载的@Value
中获取@PropertySource
。
编辑:占位符实际上不起作用。使用以下语法时:
${table.name}.columns=personId,firstName,lastName
和@Value("${${table.name}.columns}")
发生以下异常:
Could not resolve placeholder 'person.columns' in string value "${${table.name}.columns}"
问题
如何解决有关加载多个属性文件然后以java配置样式方式(但仍使用相同的键名)从每个单独的属性文件中检索值的问题?
编辑2:部分解决方案/解决方法
管理以创建关于值冲突的变通方法解决方案:
@PropertySource(value="classpath:properties/tables/tables.properties")
@PropertySource(value="classpath:properties/tables/person.properties")
@PropertySource(value="classpath:properties/tables/address.properties")
@Component
public class Sample {
private static final String COLUMNS = ".columns";
private static final String DATA_TYPES = ".data.types";
@Autowired
private Environment env;
@Value("${table.names}")
private String[] tableNames;
@PostConstruct
public void init() {
for (String tableName : tableNames) {
getTableValues(tableName);
}
}
private void getTableValues(String tableName) {
String col = env.getProperty(tableName + COLUMNS);
List<String> columns = Arrays.asList(col.split("\\s*,\\s*"));
for (String column : columns) {
System.out.println(String.format("The table %s contains the column %s", tableName, column));
}
String types = env.getProperty(tableName + DATA_TYPES);
List<String> dataTypes = Arrays.asList(types.split("\\s*,\\s*"));
// do more stuff
}
}