面试机试:做一个根据路径动态读取propertis文件的Demo
可以下通过两种方式实现:
1.使用java.util.Properties通过反射将配置文件读取到实体类中
2.通过SpringBoot的ConfigurationProperties自动读取文件,然后在pom文件中配置profiles,通过profiles切换Spring配置文件与properties文件
第一种方法比较古老了
工具类代码
public static <T> T readPropertiesToObject(Class<T> clazz,String configPath,String prefix) throws Exception {
Properties prop=readProperties(configPath);
Field[] fields = clazz.getDeclaredFields();
T result=clazz.newInstance();
for(Field field:fields){
String fieldName=field.getName();
String propName= StringUtils.isEmpty(prefix)?fieldName:prefix+"."+fieldName;
if (prop.get(propName)!=null){
field.setAccessible(true);
field.set(result,prop.get(propName));
}
}
return result;
}
public static Properties readProperties(String configPath)throws Exception{
FileInputStream fis=null;
try {
File file=new File(PropertiesUtil.class.getClassLoader().getResource(configPath).getFile());
if (!file.exists()){
log.error("file isn't exists. ["+file.getAbsolutePath()+"]");
throw new FileNotFoundException();
}
fis=new FileInputStream(file);
Properties prop=new Properties();
prop.load(fis);
return prop;
} catch (Exception e) {
e.printStackTrace();
log.error("read file exception :"+e);
throw e;
}finally {
if (fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
log.error("FileInputStream close exception :"+e);
}
}
}
}
spring读取的方式:
实体类上增加注解@PropertySource(value=“classpath:authinfo-${spring.profiles.active}.properties”,ignoreResourceNotFound = true,encoding = “utf-8”)
ignoreResourceNotFound 标书如果找不到配置文件spring不会报错,默认为false
@ConfigurationProperties(prefix = “auth”)
配置文件属性的前缀
实体类(配置文件装载类)
@Component
@Data
@PropertySource(value="classpath:authinfo-${spring.profiles.active}.properties",ignoreResourceNotFound = true,encoding = "utf-8")
@ConfigurationProperties(prefix = "auth")
public class Authinfo {
private String orgName;
private String userName;
private String password;
private String userId;
private String serverPath;
public String toString(){
return orgName+" --- "
+userName+" --- "
+password+" --- "
+userId+" --- "
+serverPath;
}
}
pom文件中添加profiles配置
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
<port>8080</port>
<cxt>/dev</cxt>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prd</id>
<properties>
<env>prd</env>
<port>8088</port>
<cxt>/prd</cxt>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<env>test</env>
<port>8082</port>
<cxt>/test</cxt>
</properties>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
</profile>
</profiles>
spring配置文件
使用占位符@@读取pom文件中activeByDefault为true的profile中的properties
spring.profiles.active设置spring读取的配置文件,通过占位符方便切换
spring:
profiles:
active: @env@
server:
port: @port@
servlet:
context-path: @cxt@
Spring配置文件用到@@获取Pom中的变量要须继承spring-boot-starter-parent
或者添加resource的flitering
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*.*</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
或
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
</parent>
springboot启动类上增加注解@EnableConfigurationProperties,设置配置文件对应实体类
@SpringBootApplication
@EnableConfigurationProperties(value = {Authinfo.class})
public class PropertiesLoaderApplication {
public static void main(String[] args) {
SpringApplication.run(PropertiesLoaderApplication.class, args);
}
//PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是 BeanFactoryPostProcessor接口的一个实现。
//在Spring中,使用PropertyPlaceholderConfigurer可以在XML配置文件中加入外部属性文件,当然也可以指定外部文件的编码。PropertyPlaceholderConfigurer可以将上下文(配置文 件)中的属性值放在另一个单独的标准java Properties文件中去。在XML文件中用${key}替换指定的properties文件中的值。这样的话,只需要对properties文件进 行修改,而不用对xml配置文件进行修改
/*@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
PropertySourcesPlaceholderConfigurer c = new PropertySourcesPlaceholderConfigurer();
c.setIgnoreUnresolvablePlaceholders(true);
return c;
}*/
}
properties配置文件
auth.userName=dev
auth.password=123456
配置文件结构
注入
@Autowired
private Authinfo authinfo;
private static String HTTP_URL ;
@Value(value = "${message.service.url:default}")
public void setURL(String path){
HTTP_URL=path;
System.out.println(path);
}
通过修改Pom文件切换配置文件切换环境