Java Properties配置梳理

以数据库连接为例,展示如何进行属性配置。

直接使用

JDBCUtil对数据库进行操作:

public class JDBCUtil {

    public static final String URL = "jdbc:mysql://localhost:3306/jdbctest";
    public static final String USER = "root";
    public static final String PASSWORD = "password";
    public static final String DRIVER = "com.mysql.cj.jdbc.Driver";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            // 1.加载驱动程序
            Class.forName(DRIVER);
            //2.获得数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            //3.操作数据库
            stmt = conn.createStatement();
            //4.实现增删改查
            rs = stmt.executeQuery("SELECT * FROM user;");


            //如果有数据,rs.next()返回true
            while (rs.next()) {
                System.out.println("username= " + rs.getString("username") + ", password= "
                        + rs.getString("password") + ", name= " + rs.getString("name"));
            }

            stmt.close();
            conn.close();
        } catch (ClassNotFoundException ex1) {
            ex1.printStackTrace();
        } catch (SQLException ex2) {
            ex2.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException sqlEx) {
                    //
                }
                rs = null;
                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException sqlEx) {
                        //
                    }
                    conn = null;
                    if (conn != null) {
                        try {
                            conn.close();
                        } catch (SQLException sqlEx) {
                            //
                        }
                        conn = null; //垃圾回收机制会更早地垃圾释放

                    }
                }
            }
        }
    }

其中,urlusernamepassworddriverClassName等数据库连接所需的参数属性直接在代码中写死,后续如果有变化,需要更改所有使用的地方。所以,现在需要把这些属性从代码中单独抽取到配置文件中。

属性读取

将属性抽取到datasource.properties文件中:

# 驱动的Java类名
mydatasource.driverClassName=com.mysql.cj.jdbc.Driver
#传递给JDBC驱动的用于建立连接的URL
mydatasource.url=jdbc:mysql://localhost:3306/jdbctest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
#用户名和密码
mydatasource.username=root
mydatasource.password=1234

代码中使用DataSource对象:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DataSource {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
}

配置文件到对象的映射如下:

public class DataSourceFactory {
    public static DataSource getDataSource() throws IOException {
        InputStream inputStream = DataSourceFactory.class.getResourceAsStream("/datasource.properties");
        Properties properties = new Properties();
        properties.load(inputStream);

        DataSource dataSource = DataSource.builder()
                .driverClassName(properties.getProperty("mydatasource.driverClassName"))
                .url(properties.getProperty("mydatasource.url"))
                .username(properties.getProperty("mydatasource.username"))
                .password(properties.getProperty("mydatasource.password"))
                .build();
        return dataSource;
    }
}

然后我们的数据库操作代码就变成了:

public class JDBCUtil {

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            DataSource dataSource = DataSourceFactory.getDataSource();
            // 1.加载驱动程序
            Class.forName(dataSource.getUrl());

            //2.获得数据库连接
            conn = DriverManager.getConnection(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
            //3.操作数据库
            stmt = conn.createStatement();
            //4.实现增删改查
            rs = stmt.executeQuery("SELECT * FROM user;");


            //如果有数据,rs.next()返回true
            while (rs.next()) {
                System.out.println("username= " + rs.getString("username") + ", password= "
                        + rs.getString("password") + ", name= " + rs.getString("name"));
            }

            stmt.close();
            conn.close();
        } catch (ClassNotFoundException ex1) {
            ex1.printStackTrace();
        } catch (Exception ex2) {
            ex2.printStackTrace();
        } finally {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException sqlEx) {
                    //
                }
                rs = null;
                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException sqlEx) {
                        //
                    }
                    conn = null;
                    if (conn != null) {
                        try {
                            conn.close();
                        } catch (SQLException sqlEx) {
                            //
                        }
                        conn = null; //垃圾回收机制会更早地垃圾释放

                    }
                }
            }
        }
    }
}

PropertySource

在Spring项目中可以使用PropertySource配置文件到对象的映射:

# 驱动的Java类名
mydatasource.driverClassName=com.mysql.cj.jdbc.Driver
#传递给JDBC驱动的用于建立连接的URL
mydatasource.url=jdbc:mysql://localhost:3306/jdbctest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
#用户名和密码
mydatasource.username=root
mydatasource.password=1234
@Data
@Component
@PropertySource("datasource.properties")
public class DataSource {
    @Value("${mydatasource.driverClassName}")
    private String driverClassName;

    @Value("${mydatasource.url}")
    private String url;

    @Value("${mydatasource.username}")
    private String username;

    @Value("${mydatasource.password}")
    private String password;
}

DataSource能够直接当作bean使用

ConfigurationProperties

在SpringBoot项目中可以使用ConfigurationProperties实现配置文件(application.yml或者application.properties) 到对象的映射:

# 驱动的Java类名
mydatasource.driverClassName=com.mysql.cj.jdbc.Driver
#传递给JDBC驱动的用于建立连接的URL
mydatasource.url=jdbc:mysql://localhost:3306/jdbctest?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
#用户名和密码
mydatasource.username=root
mydatasource.password=1234
@Configuration
@ConfigurationProperties(prefix = "mydatasource")
@Data
public class DataSource {

    private String driverClassName;

    private String url;

    private String username;

    private String password;
}

配置中心

如nacos:https://nacos.io/zh-cn/docs/quick-start-spring-boot.html

  1. 添加依赖。
<dependency>
 <groupId>com.alibaba.boot</groupId>
 <artifactId>nacos-config-spring-boot-starter</artifactId>
 <version>${latest.version}</version>
</dependency>
  1. 在 application.properties 中配置 Nacos server 的地址:
nacos.config.server-addr=127.0.0.1:8848
  1. 使用 @NacosPropertySource 加载 dataId 为 example 的配置源,并开启自动更新:
@SpringBootApplication
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfigApplication {

 public static void main(String[] args) {
     SpringApplication.run(NacosConfigApplication.class, args);
 }
}
  1. 通过 Nacos 的 @NacosValue 注解设置属性值。
@Controller
@RequestMapping("config")
public class ConfigController {

 @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
 private boolean useLocalCache;

 @RequestMapping(value = "/get", method = GET)
 @ResponseBody
 public boolean get() {
     return useLocalCache;
 }
}