Spring:使用java配置样式加载多个属性文件
给出了以下简单的spring引导示例应用程序:Spring:使用java配置样式加载多个属性文件,java,spring,properties,spring-boot,Java,Spring,Properties,Spring Boot,给出了以下简单的spring引导示例应用程序: @SpringBootApplication public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } } 及 以及以下示例属性: 地址属性: table.name=adres table.colu
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
及
以及以下示例属性:地址属性:
table.name=adres
table.columns=personId,streetName,cityName
table.data.types=integer,string,string
table.name=person
table.columns=personId,firstName,lastName
table.data.types=integer,string,string
个人财产:
table.name=adres
table.columns=personId,streetName,cityName
table.data.types=integer,string,string
table.name=person
table.columns=personId,firstName,lastName
table.data.types=integer,string,string
我想
@PropertySource
*
从目录()获取所有属性,如下所示:
@PropertySource(value="classpath*:properties/tables/*.properties")
抛出java.io.FileNotFoundException:无法打开类路径资源[properties/tables/*.properties],因为它不存在
,因此它似乎正在将*
解析为文本值而不是通配符
将属性资源占位符配置器添加到应用程序类中,如中所建议:
似乎也不起作用,因为java.io.FileNotFoundException
在加载PropertySourcesPlaceholderConfigurer
之前被抛出
二,
检索值也很困难,因为每个单独的属性使用相同的键。这样做是为了属性文件的一致性和可维护性。我已尝试使用更多占位符来解决此问题:
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
,并且只能从上次加载的@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
}
}
@PropertySource(value=“classpath:properties/tables/tables.properties”)
@PropertySource(value=“classpath:properties/tables/person.properties”)
@PropertySource(value=“classpath:properties/tables/address.properties”)
@组成部分
公共类样本{
私有静态最终字符串COLUMNS=“.COLUMNS”;
私有静态最终字符串数据类型=“.DATA.TYPES”;
@自动连线
私人环境署;
@值(“${table.names}”)
私有字符串[]表名;
@施工后
公共void init(){
for(字符串tableName:tableNames){
getTableValues(tableName);
}
}
私有void getTableValues(字符串表名){
String col=env.getProperty(tableName+COLUMNS);
列表列=数组.asList(列拆分(“\\s*,\\s*”);
for(字符串列:列){
System.out.println(String.format(“表%s包含列%s”、表名、列));
}
字符串类型=env.getProperty(tableName+数据类型);
List dataTypes=Arrays.asList(types.split(“\\s*,\\s*”);
//多做事
}
}
是的,这非常棘手,因为通常假设所有属性在所有文件中都是唯一的。我不知道怎么做,但我认为您需要做的是创建自己的属性读取器,以某种方式为所有属性预先添加文件名。也许看看这个答案,看看你是否可以创建自己的自定义资源,可以从一个目录中的多个文件加载并过滤属性。我喜欢你的想法,我想让一个属性文件包含所有其他属性文件(person、addres等)的名称,然后根据该属性文件创建“硬编码”属性文件,并使用springsEnvironment
class在其上循环并获取所需的值。这似乎是一个漫长的过程,对于一些看似微不足道的事情来说……我认为不微不足道的是,你希望属性具有相同的名称。如果文件中的所有内容都已用名称隔开,我想这会容易得多。