在使用各种各样的框架开发的时候, 通常都需要处理一些配置文件, 无论是框架自带的还是我们自己定义的, 下面对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