java如何读取外部内部 properties 内容

小鱼儿 2024-04-18 09:13 109阅读 0赞

我们通常会将一些配置,比如数据库连接信息,ftp连接信息等一些配置信息存储在 properties中,那么我们如何通过代码获得这些配置呢?


获取项目内 properties 配置内容

普通获取单个properties

properties 路径位置:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70

使用 classLoader

  1. public static void main(String[] args) throws IOException {
  2. // 1、初始化一个 properties ,注意导包是 util
  3. Properties properties = new Properties();
  4. // 2、读取 对应properties 中的数据,注意这里的地址是直接在resources下,
  5. // 如果再resources下的目录中,那么下面的 路径前也要加上该目录
  6. properties.load(PropertiesLoader.class.getClassLoader().getResourceAsStream("datasource.dev.properties"));
  7. // 3、获取对应数据
  8. String ftp_url = properties.getProperty("ftp_url");
  9. String ftp_name = properties.getProperty("ftp_name");
  10. String ftp_password = properties.getProperty("ftp_password");
  11. System.out.println("ftp_url:"+ftp_url);
  12. System.out.println("ftp_name:"+ftp_name);
  13. System.out.println("ftp_password:"+ftp_password);
  14. }

console —-》

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 1


简单的获取单个 properties 的数据上述方法是完全可行的

那么假如我们现在 在 resources/ds/ 目录下 有多个配置文件,

针对不同的业务场景,使用不同的配置

该如何呢,比如在 UAT 环境在使用一套数据库配置,在 准生产环境下使用一套配置, 在 生产环境又使用另外一套配置该如何呢。

properties 路径 ( enable 用来指定当前使用什么版本)

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 2

首先引入依赖,使用 google 帮我们封装好的工具

  1. <dependency>
  2. <groupId>com.google.guava</groupId>
  3. <artifactId>guava</artifactId>
  4. <version>19.0-rc1</version>
  5. </dependency>
  6. @Test
  7. public void getProperties() throws IOException {
  8. // 0、定义一个文件夹名,需要loader的文件夹名
  9. String path = "ds";
  10. List<String> fileNames = new ArrayList<>();
  11. // 1、 获得 classLoader
  12. ClassLoader classLoader = PropertiesLoader.class.getClassLoader();
  13. // 2、 获取 classpath 下的所有文件 ,注意导包是google的
  14. ImmutableSet<ResourceInfo> resources = ClassPath.from(classLoader).getResources();
  15. // 3、遍历 截取出我们需要的 ds 文件下的配置文件
  16. for (ResourceInfo info : resources) {
  17. if (info.getResourceName().startsWith(path)) {
  18. fileNames.add(info.getResourceName());
  19. }
  20. }
  21. Properties activeProperties = null;
  22. // 4、遍历 ds 文件夹下的配置文件,找到 enable 为true 的配置文件
  23. for (String fileName : fileNames) {
  24. if (fileName.endsWith(".properties")) {
  25. // 获得数据流
  26. InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName);
  27. // 将数据流封装到 properties 对象中
  28. Properties properties = new Properties();
  29. properties.load(stream);
  30. String enable = properties.getProperty("enable");
  31. if (enable.equalsIgnoreCase("true")) {
  32. activeProperties = properties;
  33. }
  34. }
  35. }
  36. if (activeProperties == null) {
  37. throw new IllegalArgumentException("No active datasource config found");
  38. }
  39. // 5、获取对应数据
  40. String ftp_url = activeProperties.getProperty("ftp_url");
  41. String ftp_name = activeProperties.getProperty("ftp_name");
  42. String ftp_password = activeProperties.getProperty("ftp_password");
  43. System.out.println("ftp_url:" + ftp_url);
  44. System.out.println("ftp_name:" + ftp_name);
  45. System.out.println("ftp_password:" + ftp_password);
  46. }

console—->

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 3


这样我们还是不满足,不想把指定数据源 enable 写死在程序中,

想通过 jvm 启动参数来指定使用哪个数据源

properties 还是跟上述一样

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 2

三个针对不同业务场景的配置的名字都不一样,那么我们只需要在启动项目的时候,指定一下 jvm 参数,比如我在 用户测试环境下,想使用 uat 的配置

首先指定 jvm 参数 ,在 idea 中直接加上

  1. -Dsell.activeDataSource=prod

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 4

代码如下

  1. package com.cdsn.sell.conf;
  2. import com.google.common.collect.ImmutableSet;
  3. import com.google.common.reflect.ClassPath;
  4. import com.google.common.reflect.ClassPath.ResourceInfo;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.net.URL;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.Properties;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.stereotype.Component;
  13. /**
  14. * 加载ftp配置项
  15. *
  16. * @author ch
  17. * @version 1.0.0
  18. * @since 1.0.0
  19. *
  20. * Created at 2019-09-07 09:07
  21. */
  22. @Component
  23. public class ConnectionProducer {
  24. @Bean
  25. public void connect() throws IOException {
  26. Properties properties = getProperties();
  27. // 获取对应数据
  28. String ftp_url = properties.getProperty("ftp_url");
  29. String ftp_name = properties.getProperty("ftp_name");
  30. String ftp_password = properties.getProperty("ftp_password");
  31. System.out.println("ftp_url:" + ftp_url);
  32. System.out.println("ftp_name:" + ftp_name);
  33. System.out.println("ftp_password:" + ftp_password);
  34. }
  35. public Properties getProperties() throws IOException {
  36. // 0、获取 jvm 参数
  37. String active = System.getProperty("sell.activeDataSource");
  38. // 1、获取所有对应目录下的配置文件
  39. List<String> files = getResourceFiles("ds");
  40. Properties activeProperties = null;
  41. // 2、遍历 ds 文件夹下的配置文件
  42. for (String fileName : files) {
  43. // 3、如果有jvm参数指定了配置文件名,就使用指定的
  44. // 如果没有jvm参数,则找到 enable 为true 的配置文件
  45. if (fileName.endsWith(active == null ? ".properties" : active + ".properties")) {
  46. // 获得数据流
  47. InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName);
  48. // 将数据流封装到 properties 对象中
  49. Properties properties = new Properties();
  50. properties.load(stream);
  51. // 如果 active 不存在,那么 找到 enable 为true的配置文件
  52. if (active == null || active.equalsIgnoreCase("")) {
  53. String enable = properties.getProperty("enable");
  54. if (enable.equalsIgnoreCase("true")) {
  55. activeProperties = properties;
  56. }
  57. } else {
  58. // 存在 jvm 参数指定的文件
  59. activeProperties = properties;
  60. }
  61. }
  62. }
  63. if (activeProperties == null) {
  64. throw new IllegalArgumentException("No active datasource config found");
  65. }
  66. return activeProperties;
  67. }
  68. public List<String> getResourceFiles(String path) throws IOException {
  69. List<String> fileNames = new ArrayList<>();
  70. // 1、 获得 classLoader
  71. ClassLoader classLoader = ConnectionProducer.class.getClassLoader();
  72. // 2、 获取 classpath 下的所有文件 ,注意导包是google的
  73. ImmutableSet<ResourceInfo> resources = ClassPath.from(classLoader).getResources();
  74. // 3、判断当前是否在jar中运行,如果是的话,springboot 会自己在外面有 BOOT-INF 目录
  75. URL url = ConnectionProducer.class.getResource("");
  76. String protocol = url.getProtocol();
  77. if ("jar".equals(protocol)) {
  78. // jar
  79. path = "BOOT-INF/classes/" + path;
  80. }
  81. // 4、遍历 截取出我们需要的 ds 文件下的配置文件
  82. for (ResourceInfo info : resources) {
  83. if (info.getResourceName().startsWith(path)) {
  84. fileNames.add(info.getResourceName());
  85. }
  86. }
  87. return fileNames;
  88. }
  89. }

测试结果如下

不加 jvm 参数,寻找 enable 为 true 的配置文件

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 5

加上 jvm 参数,寻找 jvm 参数对应的配置文件

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 6

=================================================

使用 java -jar 命令的时候 添加 jvm 参数

  1. java -Dsell.activeDataSource=prod -jar sell-0.0.1-SNAPSHOT.jar

获取项目外部的 properties 配置内容

首先我们需要定义一个 jvm 参数,这里设置为 sell.externalDataSource

然后在代码外部写一个 配置文件,我这里在桌面新建了一个 external.properties

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 7

java 代码如下:

  1. @Before
  2. public void setUp() throws IOException {
  3. // 设置 jvm 参数
  4. Properties p = new Properties();
  5. // 这里为 外部配置文件 全路径
  6. p.setProperty("sell.externalDataSource", "/Users/chenhao/Desktop/external.properties");
  7. System.setProperties(p);
  8. }
  9. @Test
  10. public void loadExternalDataSource() throws IOException {
  11. // 1、有没有 jvm 参数为读取外部参数
  12. String extDs = System.getProperty("sell.externalDataSource");
  13. Properties properties = null;
  14. // 2、load 外部配置文件
  15. if (extDs != null) {
  16. File f = new File(extDs);
  17. if (!f.exists()) {
  18. throw new RuntimeException("外部配置文件不存在");
  19. }
  20. // 3、写入 properties 对象
  21. properties = new Properties();
  22. properties.load(new FileInputStream(f));
  23. }
  24. // 4、获取对应数据
  25. String ftp_url = properties.getProperty("ftp_url");
  26. String ftp_name = properties.getProperty("ftp_name");
  27. String ftp_password = properties.getProperty("ftp_password");
  28. System.out.println("ftp_url:" + ftp_url);
  29. System.out.println("ftp_name:" + ftp_name);
  30. System.out.println("ftp_password:" + ftp_password);
  31. }

console —>

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5oYW9fY19o_size_16_color_FFFFFF_t_70 8

#


综上所述, 需求为 设置配置信息的优先级为

外部配置文件 > 指定的内部配置文件 > 内部配置文件 enable 为 true 的配置文件

  1. package com.cdsn.sell.conf;
  2. import com.google.common.collect.ImmutableSet;
  3. import com.google.common.reflect.ClassPath;
  4. import com.google.common.reflect.ClassPath.ResourceInfo;
  5. import java.io.File;
  6. import java.io.FileInputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.net.URL;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. import java.util.Properties;
  13. import org.springframework.context.annotation.Bean;
  14. import org.springframework.stereotype.Component;
  15. /**
  16. * 加载ftp配置项
  17. *
  18. * @author ch
  19. * @version 1.0.0
  20. * @since 1.0.0
  21. *
  22. * Created at 2019-09-07 09:07
  23. */
  24. @Component
  25. public class ConnectionProducer {
  26. @Bean
  27. public void connect() throws IOException {
  28. Properties properties = getProperties();
  29. // 获取对应数据
  30. String ftp_url = properties.getProperty("ftp_url");
  31. String ftp_name = properties.getProperty("ftp_name");
  32. String ftp_password = properties.getProperty("ftp_password");
  33. System.out.println("ftp_url:" + ftp_url);
  34. System.out.println("ftp_name:" + ftp_name);
  35. System.out.println("ftp_password:" + ftp_password);
  36. }
  37. public Properties getProperties() throws IOException {
  38. Properties activeProperties = null;
  39. // 1、首先获取 优先级 最高的外部配置文件
  40. String extDs = System.getProperty("sell.externalDataSource");
  41. if (extDs != null) {
  42. // 如果 jvm 参数中存在指定配置文件为外部,则读取外部配置文件
  43. File dataSourceFile = new File(extDs);
  44. if (!dataSourceFile.exists()) {
  45. throw new RuntimeException("外部配置文件不存在,请重新检查路径!");
  46. }
  47. activeProperties = new Properties();
  48. activeProperties.load(new FileInputStream(dataSourceFile));
  49. } else {
  50. // 2、其次获取优先级为2 的 jvm 参数
  51. String active = System.getProperty("sell.activeDataSource");
  52. // 3、获取所有对应目录下的配置文件
  53. List<String> files = getResourceFiles("ds");
  54. // 4、遍历 ds 文件夹下的配置文件
  55. for (String fileName : files) {
  56. // 5、如果有jvm参数指定了配置文件名,就使用指定的
  57. // 如果没有jvm参数,则找到 enable 为true 的配置文件
  58. if (fileName.endsWith(active == null ? ".properties" : active + ".properties")) {
  59. // 获得数据流
  60. InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName);
  61. // 将数据流封装到 properties 对象中
  62. Properties properties = new Properties();
  63. properties.load(stream);
  64. // 如果 active 不存在,那么 找到 enable 为true的配置文件
  65. if (active == null || active.equalsIgnoreCase("")) {
  66. String enable = properties.getProperty("enable");
  67. if (enable.equalsIgnoreCase("true")) {
  68. activeProperties = properties;
  69. }
  70. } else {
  71. // 存在 jvm 参数指定的文件
  72. activeProperties = properties;
  73. }
  74. }
  75. }
  76. }
  77. if (activeProperties == null) {
  78. throw new IllegalArgumentException("No active datasource config found");
  79. }
  80. return activeProperties;
  81. }
  82. public List<String> getResourceFiles(String path) throws IOException {
  83. List<String> fileNames = new ArrayList<>();
  84. // 1、 获得 classLoader
  85. ClassLoader classLoader = ConnectionProducer.class.getClassLoader();
  86. // 2、 获取 classpath 下的所有文件 ,注意导包是google的
  87. ImmutableSet<ResourceInfo> resources = ClassPath.from(classLoader).getResources();
  88. // 3、判断当前是否在jar中运行,如果是的话,springboot 会自己在外面有 BOOT-INF 目录
  89. URL url = ConnectionProducer.class.getResource("");
  90. // 获取协议
  91. String protocol = url.getProtocol();
  92. System.out.println(protocol);
  93. if ("jar".equals(protocol)) {
  94. // jar
  95. path = "BOOT-INF/classes/" + path;
  96. }
  97. // 4、遍历 截取出我们需要的 ds 文件下的配置文件
  98. for (ResourceInfo info : resources) {
  99. if (info.getResourceName().startsWith(path)) {
  100. fileNames.add(info.getResourceName());
  101. }
  102. }
  103. return fileNames;
  104. }
  105. }

发表评论

表情:
评论列表 (有 0 条评论,109人围观)

还没有评论,来说两句吧...

相关阅读