Spring Boot配置,读取配置文件

时间:2023-03-09 19:32:39
Spring Boot配置,读取配置文件

Spring Boot简化了Spring配置的管理和读取,只需要一个application.properties,并提供了多种读取配置文件的方式。

一、配置Spring Boot

Spring Boot默认启动的是8080端口,Web上下文是"/"。可以通过配置application.properties来重新配置Spring Boot。

SpringBoot使用两种全局的配置文件,全局配置文件可以对一些默认配置进行修改。

  • application.properties
  • application.yml

这两个配置文件使我们springboot启动的时候回默认加载的配置文件。

配置文件放在src/main/resources目录或者类路径/config下,这个配置文件的路径是有优先级的。

1.1 服务器配置

若想更换其他端口,需配置server.port,如

server.port=9000

也可以在命令行中指定启动端口,比如传入参数-server.port=9000:

java -jar shop.jar --server.port=9000

或者传入虚拟机系统属性:(较为适用)

java -Dserver.port=9000 -jar shop.jar

Spring Boot默认为应用配置的上下文访问目录是"/",可以通过配置文件或者命令行,配置server-context-path:

server-servlet.context-path=/config

常用的服务器配置属性表:

属性 描述
server.address 服务器IP绑定地址,如果你的主机有多个网卡,可以绑定一个IP地址
server.session.timeout 会话过期时间,以秒为单位
server.error.path 服务器出错后的处理路径/error
server.servlet.contextpath Spring Boot应用的上下文
server.port Spring Boot应用监听端口

1.2 使用其他Web服务器

Spring Boot内置了Tomcat,同时还支持Jetty、Undertow作为Web服务器,使用这些应用服务器,只需要引入相应的starter。

推荐使用Undertow。

server.tomcat.*包含了Tomcat的相关配置,较为重要的如下:

# 打开Tomcat的访问日志
server.tomcat.accesslog.enabled=true
# 访问日志所在的目录
server.tomcat.accesslog.directory=logs
# 允许HTTP请求缓存到请求队列的最大个数,默认不限制
server.tomcat.accept-count=
# 最大连接数,默认不限制,如果一旦连接数到达,剩下的连接将会保存到请求缓存队列里,也就是accept-count指定队列
server.tomcat.max-connections=
# 最大工作线程数
server.tomcat.max-threads=
# HTTP POST内容最大长度,默认不限制
server.tomcat.max-http-post-size

1.3 配置启动信息

默认启动后,控制台打印"Spring":

可以在classpath中增加banner.txt,显示你自己的输出信息。在Spring Boot项目的resources目录下新建一个banner.txt,内容如下:

#####Hello , hhhhh

再次运行,会发现启动信息已经改变。

也可设置banner.gif(png,jpg),控制台自动将图片转为ASCII字符,作为启动信息输出,将图片复制到resources目录下即可。

banner.charset=UTF-8 # banner.txt 字符集
banner.location=classpath:banner.txt
banner.image.location=classpath:banner.gif # 如果使用图片,图片的位置可以使用jgp/png
banner.image.width= 76 # 图片宽度,这里指转为字符的个数,越多越清楚
banner.image.heigjt=76 # 图片长度
banner.image.margin= 2 # 图片与左边的间距,默认为2个字符

1.4 配置浏览器显示ico

在项目resources目录下新建一个static目录,在static目录下创建images目录,将项目的favicon.ico放在images目录下,每个页面添加以下样式即可:

<link rel="shorcut icon" href="/images/apple.ico">

1.5 Yaml语法

YAML支持的三种数据结构。

  • 字面量:普通的值。(数字,字符串,布尔)
  • 对象:键值对的集合。(Map)
  • 数组:一组按次序排列的值。(List,Set)

1.5.1 字面量

YAML中字面量属于普通的值。以key: value来表示,value前必须带一个空格。

字面量,字符串默认不需要单双引号。

双引号:会转义字符,特殊字符会被转义。(name: “SimpleWu\n lisi” //输出:SimpleWu换行 lisi)

单引号:不会转义字符,特殊字符不会被转义。(name: ‘SimpleWu\n lisi’ //输出:SimpleWu\n lisi)

Copyserver:
port: 8081

1.5.2 对象、Map

在YAML中,对象和Map都是以键值对的方式表示。在下一行来编写属性和值得关系,注意缩进。

Copyusers:
firstName: SimpleWu
email: lovelyWu98k@gmail.com

或者:

Copyusers: {
firstName: zhangsan,
email: lovelyWu98k@gmail.com
}

1.5.3 数组

用-值得方式来表示数组中的一个元素。

Copyusers:
- SimpleWu
- lovelyWu98k@gmail.com
- addressisnot
Copyusers: [SimpleWu,lovelyWu98k@gmail.com,addressisnot]

二、日志配置

默认情况下,不需要对日志做任何配置就可以使用,Spring Boot使用LogBack作为日志的实现,使用apache Commons Logging作为日志接口。

public class HelloworldController {
private Log log = LogFactory.getLog(HelloworldController.class);
...
}

日志每行格式内容有:

  • 日期和时间;
  • 日志级别,有ERROR、WARN、INFO、DEBUG和TRACE;
  • 进程id,Spring Boot应用的进程id;
  • [xxx],线程的名称;
  • 类名;
  • 消息体。

默认情况下,INFO级别以上的信息才会打印到控制台,可以自己设定日志输出级别

,比如在application.properties中加入以下代码:

logging.level.root=info
# org包下的日志级别
logging.level.org=warn
logging.level.com.yourcorp=debug

指定默认的级别是INFO,org开头的类,日志级别是WARN。

Spring Boot默认并输出日志到文件,可以在application.properties中指定日志输出:

logging.file = my.log

也可指定日志存放的路径,如:

logging.path=e:/temp/log

当日志到达10MB的时候,会自动冲洗生成一个新日志文件。

Spring Boot支持对控制台日志输出和文件输出进行格式控制,如(仅使用内置的logback):

logging.pattern.console=%level %date{HH:mm:ss} %logger{20}.%M %L :%m%n
logging.pattern.file= %level %date{ISO8601} [%thread} %logger{20}. %M %L :%m%n
  • %level,日志输出级别
  • %date,日志发生时的时间,ISO8601则是标准日期输出格式
  • %logger,用于输出Logger的名字,包名+类名,{n}限定长度。
  • %thread,当前线程名
  • %M,日志发生时的方法名字;
  • %L,日志调用所在的代码行。
  • %m,日志消息
  • %n,日志换行

通过参数–debug将系统日志级别调整为debug方式。

java -jar app.jar --debug

三、读取应用配置

可以在应用中读取application.properties文件,Spring Boot提供了三种方式,通用的Environment,可以通过key-value方式获取到其中的值,也可通过@Value注解,自动注入属性值,还可将一组属性自动注入到一个配置类中。

3.1 Environment

Environment是一个通用的读取应用程序运行时的环境变量的类,可以读取application.properties、命令行输入参数、系统属性、操作系统环境变量等。可以通过Spring容器自动注入,比如在Spring管理的Bean中:

@Configuration
public class EvnConfig {
@Autowried private Environment env;
public int getServerPort(){
return env.getProperty("server.port",Inter\ger.class);
}
}

读取的例子:

读取 返回值
env.getProperty(“user.dir”) 程序运行的目录
env.getProperty(“user.home”) 执行程序的用户的home目录
env.getProperty(“JAVA_HOME”) 读取环境的环境变量

3.2 @Value

直接通过@Value注解注入一个配置信息到Spring管理的Bean中:

@RequestMapping("/showvalue.html")
public @ResponseBody String value(@Value("${server.port}") int port{
return "port:"+port;
}

3.3 @ConfigurationProperties

通常情况下,将一组同样类型的配置属性映射为一个类更为方便,比如服务器配置,在application.properties中写成如下配置:

server.port=9090
server.context-path=/config

以上三个配置属性都与Web服务器配置相关,都有server前缀,因此可以使用@ConfigurationProperties来获取这一组实现,如:

@ConfigurationProperties
@Configuration
public class ServerConfig{
private int port;
private String contextPath;
public int getPort() {
return port;
}
public void serPort(int port){
this.port=port;
}
//contextPath同理;
}

在处理ConfigurationProperties注解的类的时候,自动会将“-”或者“_”去掉,转化为Java命名规范。

LibraryProperties 类上加了 @Component 注解,我们可以像使用普通 bean 一样将其注入到类中使用。

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component; import java.util.List; @Component
@ConfigurationProperties(prefix = "library")
@Setter
@Getter
@ToString
class LibraryProperties {
private String location;
private List<Book> books; @Setter
@Getter
@ToString
static class Book {
String name;
String description;
}

这个时候你就可以像使用普通 bean 一样,将其注入到类中使用:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; /**
* @author shuang.kou
*/
@SpringBootApplication
public class ReadConfigPropertiesApplication implements InitializingBean { private final LibraryProperties library; public ReadConfigPropertiesApplication(LibraryProperties library) {
this.library = library;
} public static void main(String[] args) {
SpringApplication.run(ReadConfigPropertiesApplication.class, args);
} @Override
public void afterPropertiesSet() {
System.out.println(library.getLocation());
System.out.println(library.getBooks()); }
}

3.3.1 通过@ConfigurationProperties读取并校验

将application.yml修改为如下内容,明显看出这不是一个正确的 email 格式:

my-profile:
name: Guide哥
email: koushuangbwcx@

ProfileProperties 类没有加 @Component 注解。我们在我们要使用ProfileProperties 的地方使用@EnableConfigurationProperties注册我们的配置 bean:

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated; import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty; @Getter
@Setter
@ToString
@ConfigurationProperties("my-profile")
@Validated
public class ProfileProperties {
@NotEmpty
private String name; @Email
@NotEmpty
private String email; //配置文件中没有读取到的话就用默认值
private Boolean handsome = Boolean.TRUE; }
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties; @SpringBootApplication
@EnableConfigurationProperties(ProfileProperties.class)
public class ReadConfigPropertiesApplication implements InitializingBean {
private final ProfileProperties profileProperties; public ReadConfigPropertiesApplication(ProfileProperties profileProperties) {
this.profileProperties = profileProperties;
} public static void main(String[] args) {
SpringApplication.run(ReadConfigPropertiesApplication.class, args);
} @Override
public void afterPropertiesSet() {
System.out.println(profileProperties.toString());
}
}

因为我们的邮箱格式不正确,所以程序运行的时候就报错,根本运行不起来,保证了数据类型的安全性:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'my-profile' to cn.javaguide.readconfigproperties.ProfileProperties failed:

    Property: my-profile.email
Value: koushuangbwcx@
Origin: class path resource [application.yml]:5:10
Reason: must be a well-formed email address

我们把邮箱测试改为正确的之后再运行,控制台就能成功打印出读取到的信息:

ProfileProperties(name=Guide哥, email=koushuangbwcx@163.com, handsome=true)

3.4 @PropertySource读取指定 properties 文件

import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component; @Component
@PropertySource("classpath:website.properties")
@Getter
@Setter
class WebSite {
@Value("${url}")
private String url;
}

使用:

@Autowired
private WebSite webSite; System.out.println(webSite.getUrl());//https://javaguide.cn/

四、Spring Boot自动装配

Spring 提供了Java配置的核心就是使用@Configuration作用在类上,并且联合在此类上多个@Bean注解的方法,声明Spring管理的Bean。

@Configuration
public class Configuration {
@Bean("bean")
public Bean getBean(){
return new Bean();
}
}

可以在@Bean注解的方法上提供任意参数来说明依赖,比如Service需要依赖数据源datasource:

@Bean
public Service getService(DataSource datasource){
return new Service (datasource);
}

在配置好Bean后,可以通过@Autowired在任何地方自动注入。

@Service
public class Service{
@Autowired Service service;
}

4.1 Bean条件装配

4.2 Class条件装配

4.3 Environment装配

4.4 其他条件装配

4.5 联合多个条件

五、配置文件加载位置和顺序

springboot启动会扫描一下位置的配置文件作为springboot的默认配置文件。

  • 项目路径下的config文件夹
  • 项目路径下
  • classpath路径下config文件夹
  • classpath路径下

以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,如果冲突的情况,高优先级配置内容会覆盖低优先级配置内容。如果不冲突,形成互补配置。

我们也可以通过配置spring.config.location来改变默认配置。使用命令行方式加载,否则优先级不够。

Copyjava –jar xxxx.jar –spring.config.location=配置文件路径

六、外部配置加载顺序

SpringBoot也可以从以下位置加载配置;优先级从高到低,高优先级的配置覆盖低优先级的配置,所有配置形成互补配置。

  • 命令行参数
  • 来自java:comp/env的JNDI属性
  • Java系统属性(System.getProperties())
  • 操作系统环境变量
  • RandomValuePropertySource配置的random.*属性值
  • jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  • jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  • jar包外部的application.properties或application.yml(不带spring.profile)配置文件
  • jar包内部的application.properties或application.yml(不带spring.profile)配置文件
  • @Configuration注解类上的@PropertySource
  • 通过SpringApplication.setDefaultProperties指定的默认属性

七、加载外部配置文件

对配置中的内容进行拆分,拆分到多个文件中。这样就提高了配置的可维护性。

引入外部配置文件:

  • @PropertySource(value={“classpath:student.properties”})
  • @ImportResource(locations={“classpath:spring.xml”}
  • @Configuration和@Bean方式。(SpringBoot推荐方式)

第一种方式:@ProperSource方式:需要注入的类的前面使用该注解。

第二种方式:@ImportResource方式首先添加一个spring的配置文件,在里面添加需要映射的类。在启动的SpringBootApplication前面使用该注解

第三种方式:@Configuration和@Bean方式添加一个自定义配置类。

Copy//第三种方式
@Configuration
public class MyConfig {
//将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
@Bean
public MySQLInfo mySQLInfo(){
System.out.println("配置类@Bean给容器中添加组件了...");
return new MySQLInfo();
}
}

八、切换多个外部配置文件

比如现在我们有三个配置文件:

  • application.yml
  • application-dev.yml
  • application-prod.yml