在使用各种各样的框架开发的时候, 通常都需要处理一些配置文件, 无论是框架自带的还是我们自己定义的, 下面对Spring boot中读取配置文件的方法做一个总结.
配置文件可以有多种格式, 理论上只要你能从里面把需要的信息读取出来, 你想怎么存就怎么存, 不过还是有几种主流的配置方式.
下面对两种主要的配置文件格式: properties, yaml
进行总结.
现在要在项目中使用阿里的druid连接池, 把需要的参数都写入到properties配置文件中.
先建立一个项目, 项目结构如下:
.
├── build.gradle
├── settings.gradle
└── src
├── main
│ ├── java
│ │ └── top
│ │ └── zenghao
│ │ └── config
│ │ ├── config
│ │ │ └── DbConfig.java
│ │ └── ConfigApplication.java
│ └── resources
│ ├── application.properties
│ ├── db.properties
│ ├── static
│ └── templates
└── test
└── java
└── top
└── zenghao
└── config
└── ConfigApplicationTests.java
17 directories, 11 files
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'top.zenghao'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
测试代码: ConfigApplication.java
package top.zenghao.config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.sql.DataSource;
import javax.xml.crypto.Data;
import java.sql.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigApplicationTests {
@Autowired
private DataSource dataSource;
@Test
public void testDataSourceProperties() throws SQLException {
String create_sql = "create table if not exists testproperties(" +
"id int primary key," +
"message varchar(50));";
String drop_sql = "drop table testproperties";
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(create_sql);
statement.execute();
PreparedStatement dropStatement = connection.prepareStatement(drop_sql);
dropStatement.execute();
}
}
通过注入的Enviroment变量, 我们可以从中获取到application.properties中的参数, 使用这个方法必须把参数写到application.properties中.
jdbc.url=jdbc:mysql://localhost:3306/testdb jdbc.user=root jdbc.password=pass jdbc.driver=com.mysql.jdbc.Driver
package top.zenghao.config.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import javax.sql.DataSource;
@Configuration
public class DbConfig {
@Autowired
private Environment env; // 注入env
@Bean
@Primary
public DataSource getDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(env.getProperty("jdbc.user"));
dataSource.setPassword(env.getProperty("jdbc.password"));
dataSource.setDriverClassName(env.getProperty("jdbc.driver"));
dataSource.setUrl(env.getProperty("jdbc.url"));
return dataSource;
}
}
@ConfigurationProperties
注解自动读取
使用 @ConfigurationProperties
注解, Spring 会帮我们读取指定properties文件中的参数, 并且映射到相应的类字段中. 指明properties文件使用 @PropertySource
现在我们不把参数放到 application.properties
文件里面了, 而是新建一个配置文件 db.properties
:
jdbc.url=jdbc:mysql://localhost:3306/testdb jdbc.user=root jdbc.password=pass jdbc.driver=com.mysql.jdbc.Driver
然后再新建一个Properties类
package top.zenghao.config.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ConfigurationProperties(prefix = "jdbc")
@PropertySource("classpath:db.properties")
public class DbConfigProperties {
private String url;
private String driver;
private String user;
private String password;
// getters and setters
}
在DbConfig.java中注册一个Bean:
package top.zenghao.config.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import javax.sql.DataSource;
@Configuration
public class DbConfig {
@Autowired
private DbConfigProperties dbConfigProperties;
/**
* 方法二, 使用注解自动读取
*/
@Bean
@Primary
public DataSource getDataSource2() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(dbConfigProperties.getUser());
dataSource.setPassword(dbConfigProperties.getPassword());
dataSource.setUrl(dbConfigProperties.getUrl());
dataSource.setDriverClassName(dbConfigProperties.getDriver());
return dataSource;
}
}
嗯~看上去和第一种差不多, 不过这次我们能读取自定义的properties文件了.
spring会对 @Value
注解的对象进行注入, 注入的内容是可以是 application.properties
中的配置属性, 也可以是别的, 具体需要看@Value的文档, 这里不展开讲. 注入的语法是SpEL, 例如下面这样:
@Bean
@Primary
*/
public DataSource getDataSource3(@Value("${jdbc.user}") String user,
@Value("${jdbc.password}") String password,
@Value("${jdbc.driver}") String driver,
@Value("${jdbc.url}") String url) {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
return dataSource;
}
这个方法其实挺原始的, 不过它有用.
@Bean
@Primary
public DataSource getDataSource4() throws IOException {
// Bundle 使用方法一
/*
ResourceBundle bundle
= new PropertyResourceBundle(getClass().getClassLoader().getResourceAsStream("db.properties"));
*/
// Bundle 方法二
ResourceBundle bundle = ResourceBundle.getBundle("db");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(bundle.getString("jdbc.user"));
dataSource.setPassword(bundle.getString("jdbc.password"));
dataSource.setUrl(bundle.getString("jdbc.url"));
dataSource.setDriverClassName(bundle.getString("jdbc.driver"));
return dataSource;
}
这是spring boot引入的一种新的配置方式, 其实除了在语法上properties不同之外, 其它都差不多, 他们都可以使用上面所说的前三种方式读取. 这里没有一一说出的必要, 代码链接在文末.
如果配置参数是写在了 application.properties
中, 可以使用 Environment
方法或者 @Value
注解;
如果配置参数是写在自定义的文件中, 使用 @ConfigurationProperties
注解或者使用Bundle读取.
项目地址: springboot-read-config-file