springboot配置详解
springboot如何从配置文件中读取配置。
springboot默认的全局配置文件在application.properties
或application.yml
(推荐使用)。此文件默认可以放在classpath
路径,或者放在classpath:/config
,springboot应用都是默认读取到的。
加入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
一个小入门demo:
在application.properties中定义了一属性
local.ip=192.168.1.111
启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
System.out.println(context.getEnvironment().getProperty("local.ip"));
context.close();
}
}
运行程序:
192.168.1.111
我们发现 context.getEnvironment()
源码:
/**
* Return the {@code Environment} for this application context in configurable
* form, allowing for further customization.
* @since 3.1
*/
@Override
ConfigurableEnvironment getEnvironment();
而 ConfigurableEnvironment
一定是继承Environment,关于 ConfigurableEnvironment
和 Environment
我们不过多解释。
使用 Environment类或者@ Value 注解获取配置
定义一个 UserConfig
,并纳入spring容器中管理
@Component
public class UserConfig {
@Autowired
private Environment environment;
@Value("${local.name}")
private String localName;
@Value("${local.port}")
private int port;
public void show(){
System.out.println(environment.getProperty("local.ip"));
//重载方法,使得读取到的数据是Integer类型的
System.out.println(environment.getProperty("local.port",Integer.class));
System.out.println(localName);
System.out.println(port);
//在配置文件中引用引用已有的变量
System.out.println(environment.getProperty("local.url"));
}
}
配置文件:
local.ip=192.168.1.111
local.name=zhihao.miao
local.port=9090
local.url=http://${local.ip}:${local.port}
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
UserConfig userConfig = context.getBean(UserConfig.class);
userConfig.show();
context.close();
}
}
打印结果:
192.168.1.111
9090
zhihao.miao
9090
http://192.168.1.111:9090
给属性增加默认值
定义一个普通的类 UserConfig2
,纳入到spring容器中管理
@Component
public class UserConfig2 {
@Value("${tomcat.port:10000}")
private int port;
@Autowired
private Environment environment;
public void show(){
System.out.println(port);
System.out.println(environment.getProperty("tomcat.port",Integer.class,10000));
}
}
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
UserConfig2 userConfig = context.getBean(UserConfig2.class);
userConfig.show();
context.close();
}
}
打印结果:
10000
10000
如果在配置文件中设置了此属性则会覆盖该属性, application.proterties
配置如下:
tomcat.port=10001
则打印结果如下:
10001
10001
还有一种配置默认值,使用
SpringApplication.setDefaultProperties(Map<String, Object> defaultProperties)
SpringApplication.setDefaultProperties(Properties defaultProperties)
二个方法,也可以设置:
package com.zhihao.miao;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@SpringBootApplication
public class Application {
@Value("${server.host:localhost}")
private String serverHost;
public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
Map<String,Object> defaultProperties = new HashMap<>();
defaultProperties.put("server.host","192.168.1.111");
defaultProperties.put("server.ip","8080");
application.setDefaultProperties(defaultProperties);
// Properties defaultProperties2 = new Properties();
// defaultProperties2.put("server.ip","8080");
// application.setDefaultProperties(defaultProperties2);
ConfigurableApplicationContext context =application.run(args);
System.out.println(context.getBean(Application.class).serverHost);
System.out.println(context.getEnvironment().getProperty("server.host"));
System.out.println(context.getEnvironment().getProperty("server.ip"));
context.close();
}
}
可以覆盖了@Value注解配置的默认值,如果在application.properties中配置
server.host=129.11.1.111
server.ip=9090
那么配置文件配置的属性值就会覆盖上面的默认配置。
总结:
setDefaultProperties设置的优先级最高,如果在配置文件中设置,那么当然就是配置文件中的默认值优先级最高。
使用@ConfigurationProperties注解加载配置文件
在application.properties文件中加入配置:
ds.url=jdbc:mysql:///springboot
ds.driverClassName=com.mysql.jdbc.Driver
ds.username=root
ds.password=123456
定义一个普通的类 DataSourceConfig
,并将其纳入到spring容器中管理:
@Component
@ConfigurationProperties(prefix = "ds")
public class DataSourceConfig {
private String url;
private String driverClassName;
private String username;
private String password;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void show(){
System.out.println("ds.url===="+url);
System.out.println("ds.driverClassName==="+driverClassName);
System.out.println("ds.username====="+username);
System.out.println("ds.password====="+password);
}
}
注意:使用 @ConfigurationProperties
,那么配置的属性必须要加get**,set **方法。
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
DataSourceConfig dataSourceConfig = context.getBean(DataSourceConfig.class);
dataSourceConfig.show();
context.close();
}
}
打印结果:
ds.url====jdbc:mysql:///springboot
ds.driverClassName===com.mysql.jdbc.Driver
ds.username=====root
ds.password=====123456
加载外部文件的方式
上面说过,springboot
应用默认读取的是classpath
下的 application.properties
,比如说我在application.properties
之外定义了一个user.properties
和一个jdbc.properties
,需求是应用也要读到这些配置。
user.properties
配置如下:
jdbc.username=root
jdbc.password=123456
jdbc.properties
配置如下:
jdbc.url=jdbc:mysql://springboot
dricverClassName=com.mysql.jdbc.Driver
定义一个类 FileConfig
,使用@PropertySource
注解或者 @PropertySources
注解
package com.zhihao.miao.bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
@Configuration
//@PropertySource({"classpath:jdbc.properties","classpath:user.properties"})
@PropertySources({@PropertySource("classpath:jdbc.properties"),@PropertySource("classpath:user.properties")})
public class FileConfig {
}
@PropertySource
注解和@PropertySources
注解的区别,@PropertySources
的源码如下,
/**
* Container annotation that aggregates several {@link PropertySource} annotations.
*
* <p>Can be used natively, declaring several nested {@link PropertySource} annotations.
* Can also be used in conjunction with Java 8's support for <em>repeatable annotations</em>,
* where {@link PropertySource} can simply be declared several times on the same
* {@linkplain ElementType#TYPE type}, implicitly generating this container annotation.
*
* @author Phillip Webb
* @since 4.0
* @see PropertySource
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PropertySources {
PropertySource[] value();
}
@PropertySources
注解容器式注解,将@PropertySource
注解复合在一起使用。
配置类:
package com.zhihao.miao.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class JdbcConfig {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Value("${jdbc.url}")
private String jdbcUrl;
@Value("${dricverClassName}")
private String dricverClassName;
public void show(){
System.out.println("username====="+username);
System.out.println("password====="+password);
System.out.println("jdbcUrl====="+jdbcUrl);
System.out.println("dricverClassName==="+dricverClassName);
}
}
启动类:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
JdbcConfig jdbcConfig = context.getBean(JdbcConfig.class);
jdbcConfig.show();
context.close();
}
}
打印结果:
username=====root
password=====123456
jdbcUrl=====jdbc:mysql://springboot
dricverClassName===com.mysql.jdbc.Driver
注入集合或数组属性
先在application.properties中定义配置:
ds.hosts[0]=192.168.1.100
ds.hosts[1]=192.168.1.111
ds.hosts[2]=192.168.1.112
ds.ports[0]=8080
ds.ports[1]=8081
ds.ports[2]=8082
然后定义一个普通的类TomcatProperties,并纳入到spring容器中管理
package com.zhihao.miao.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@ConfigurationProperties("ds")
public class TomcatProperties {
private List<String> hosts = new ArrayList<>();
private String[] ports;
public List<String> getHosts() {
return hosts;
}
public void setHosts(List<String> hosts) {
this.hosts = hosts;
}
public String[] getPorts() {
return ports;
}
public void setPorts(String[] ports) {
this.ports = ports;
}
public void show(){
System.out.println("host====="+this.hosts);
System.out.println("ports======"+this.ports[0]+","+this.ports[1]+","+this.ports[2]);
}
}
注:还是需要get***,set***方法。
启动类
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class,args);
TomcatProperties tomcatProperties = context.getBean(TomcatProperties.class);
tomcatProperties.show();
context.close();
}
}
打印结果:
host=====[192.168.1.100, 192.168.1.111, 192.168.1.112]
ports======8080,8081,8082