spring boot 自定义properties使用详解

本文详细介绍了如何在Spring Boot中自定义`application.properties`配置,包括单个和多个属性的注入、配置数组、松散绑定、参数引用、随机数、自定义配置文件的使用、在方法上使用@Bean注入、自定义结构以及参数校验。通过@ConfigurationProperties、@Component、@Value等注解,可以方便地管理和使用自定义配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1) 在application.properties文件中添加自定义属性(单个属性使用);

       在这里我们新建一个maven java project进行测试,取名为:spring-boot-hello4。

对pom.xml基本的spring boot 配置,主要用到的一个核心依赖是:

1
2
3
4
5
< dependency >  
           < groupId >org.springframework.boot</ groupId >  
           < artifactId >spring-boot-configuration-processor</ artifactId >  
           < optional >true</ optional >  
</ dependency >

官方中对于spring-boot-configuration-processor是这么说明的:

通过使用spring-boot-configuration-processor jar, 你可以从被@ConfigurationProperties注解的节点轻松的产生自己的配置元数据文件。该jar包含一个在你的项目编译时会被调用的Java注解处理器。想要使用该处理器,你只需简单添加spring-boot-configuration-processor依赖。

好了,官方已经说得很清楚了,这个依赖主要可以在代码中轻松的使用@ConfigurationProperties注解注入属性文件配置的属性值。

单属性注入的比较简单,只需要在application.properties加入配置,如下:

1
2
#key = value的形式;  
filePathLocation = d:/data/files

那么在对应需要使用的类中使用如下代码进行引入:

1
2
@Value ( "${filePathLocation}" )  
private  String filePathLocation;

这里使用@Value注解就可以为我们的变量filePathLocation设置上我们在application.properties文件中设置的key值了。

在实际开发中可能我们期望的是,如果没有设置key的话,设置一个默认值,使用如下代码即可实现(以上@Value的使用方式如果在没有设置key的话是会抛出异常的):

1
2
@Value ( "${filePathLocation1:d:/data/myfiles}" )  
private  String filePathLocation1;

这里的filePathLocation1我们并没有在application.properties文件中进行指定,但是查看打印信息是可以看到我们设置的默认值的,所以设置默认值的方式就是:

@Value(“${key:defaultVlaue}”) 的形式进行设置。

(2) 在application.properties文件中添加自定义属性(多个属性使用);


       多属性的设置也可以属性单属性的注入方式,但是这种方式不好,那么怎么比较优雅的注入多个属性值进行使用了。假设我们在application.properties定义了如下的属性:

1
2
3
4
5
6
7
8
#公司简称;
com.kfit.company.name =知远信科
#公司位置;
com.kfit.company.location =北京海淀区
#公司联系方式;
com.kfit.company.mobile =  110 **** 1195
#公司员工人数;
com.kfit.company.employCount =  100

接下来我们定义一个ComapnyProperties类进行设置这些参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package  com.kfit.properties;
  
import  org.springframework.boot.context.properties.ConfigurationProperties;
import  org.springframework.stereotype.Component;
  
//prefix设置key的前缀;
@ConfigurationProperties (prefix =  "com.kfit.company" )
@Component
public  class  CompanyProperties {
    
     private  String name;
     private  String location;
     private  String mobile;
     private  int  employCount;
     public  String getName() {
        return  name;
     }
     public  void  setName(String name) {
        this .name = name;
     }
     public  String getLocation() {
        return  location;
     }
     public  void  setLocation(String location) {
        this .location = location;
     }
     public  String getMobile() {
        return  mobile;
     }
     public  void  setMobile(String mobile) {
        this .mobile = mobile;
     }
     public  int  getEmployCount() {
        return  employCount;
     }
     public  void  setEmployCount(intemployCount) {
        this .employCount = employCount;
     }
     @Override
     public  String toString() {
        return  "CompanyProperties [name="  + name +  ", location="  + location +  ", mobile="  + mobile +  ", employCount="
               + employCount +  "]" ;
     }
}

那么之后我们就可以使用如下代码注入到要使用的这些属性的类进行使用了:

1
2
@Autowired  
private  CompanyProperties companyProperties;

这里需要注意下:


第一:我们使用了@ConfigurationProperties(prefix = "com.kfit.company") 快速注入我们的属性,这里prefix是key的公共部分。

第二:这里我们使用@Component 注解为spring 管理的类,那么在别的类才可以进行注入使用。

第三:在之前的文章中我们并没有使用@Component进行注册为spring 容器中,而是使用了@EnableConfigurationProperties({WiselySettings.class})  这样的方式进行注入的。这两种方式都可以。


(3) 配置数组注入;

我们在application.properties定义数组:

1
2
3
4
# 员工列表  
com.kfit.company.employs[ 0 ]=张三  
com.kfit.company.employs[ 1 ]=李四  
com.kfit.company.employs[ 2 ]=王五

类似这样的定义那么在对应的CompanyProperties文件中怎么接收呢?很简单,定义List<String>接收就可以了,代码如下:

1
private  List<String> employs =  new  ArrayList<String>();

这里的属性名称employs需要和application.properties文件的key是对应的。

这样employs注入了配置中的数据,打印为如下:

1
[张三, 李四, 王五]


(4) 松散的绑定;

Spring Boot使用宽松的规则用于绑定属性到@ConfigurationProperties beans,所以Environment属性名和bean属性名不需要精确匹配。常见的示例中有虚线分隔的(比如,context-path绑定到contextPath),环境属性大写转为小写字母(比如:PORT绑定port)。

示例:

在application.properties文件中的配置:

1
2
3
com.kfit.company.firstName = lin  
com.kfit.company.logo-path = d:/data/files/logo.png  
com.kfit.company.COMPANY_FULLNAME =xxxx科技公司

对应的CompanyProperties类中的对应定义:

1
2
3
4
5
6
7
8
9
10
//对应:com.kfit.company.firstName = lin  
   private  String firstName;  
    
   //对应:com.kfit.company.logo-path = d:/data/files/logo.png  
   private  String logoPath;  
    
   //对应:com.kfit.company.COMPANY_FULLNAME = 北京知远科技公司  
   private  String companyFullname;  
    
   private  List<String> employs =  new  ArrayList<String>();

看到这里,你是否终于知道为什么context-path,spring.jpa.show-sql

其实是被解释为contextPath和showSql了,不然要是指定定义一个show-sql变量是无法编译通过的,oh,原来是这么回事呢,这真是太神奇了,就是因为编程无奇不有,所以才有那么多人爱编程。


(5) 参数的引用;

在application.properties中的各个参数之间也可以直接引用来使用,就像下面的设置:

1
com.kfit.blog.desc=${com.kfit.blog.name}正在写《${com.kfit.blog.title}》

这个就很好理解了,使用${key} 的方式进行引用。


(6) 随机数;

在一些情况下,有些参数我们需要希望它不是一个固定的值,比如密钥、服务端口等。Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。

1
2
3
4
5
6
7
8
9
10
# 随机字符串  
com.kfit.blog.value=${random.value}   
# 随机 int  
com.kfit.blog.number=${random. int }   
# 随机 long  
com.kfit.blog.bignumber=${random. long }   
10 以内的随机数  
com.kfit.blog.test1=${random. int ( 10 )}   
10 - 20 的随机数  
com.kfit.blog.test2=${random. int [ 10 , 20 ]}

好了,这些在之前的文章都有介绍过了,就不多说了。


(7) 使用自定义的配置文件company.properties怎么操作;

如果我们自己定义一个company.properties文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#key = value的形式;  
filePathLocation = d:/data/files  
    
#公司简称;  
com.kfit.company.name =xxxx信科-custom  
#公司位置;  
com.kfit.company.location =北京海淀区-custom  
#公司联系方式;  
com.kfit.company.mobile =  110 **** 1195 -custom  
#公司员工人数;  
com.kfit.company.employCount =  100  
# 员工列表  
com.kfit.company.employs[ 0 ]=张三-custom  
com.kfit.company.employs[ 1 ]=李四-custom  
com.kfit.company.employs[ 2 ]=王五-custom  
    
com.kfit.company.firstName = lin-custom  
com.kfit.company.logo-path = d:/data/files/logo.png-custom  
com.kfit.company.COMPANY_FULLNAME =xxxx科技公司-custom

这个定义就是我们刚刚提到的一些配置,那么怎么引入了,如果使用上面的CompanyProperties的方式肯定是不行了,那么怎么呢?其实很简单,只需要在CompanyProperties稍微修改下即可,修改的地方如下:

1
2
3
@ConfigurationProperties (  
            prefix =  "com.kfit.company" ,  
             locations= "classpath:company.properties" )

大家注意,这里唯一不一样的地方是加入了一个属性locations指定了我们要使用的配置文件路径和名称,如果我们的配置文件不在application.properties下,可以这么定义:

classpath:config/company.properties。

好了这一个知识点就这么简单,只要掌握要点,一句代码就可以搞定。


(8) 在方法上使用@Bean的时候如何进行注入;

       这个需求点是怎么产生的呢?我们经常会配置多个数据源,那么我们有些配置还是希望从application.properties文件中进行读取,那么自然而然的在我们定义的@bean中就需要能够读取配置文件的属性。这里我们简单做个试验,我们定义CompanyProperties3,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package  com.kfit.properties;  
    
import  java.util.ArrayList;  
import  java.util.List;  
    
public  class  CompanyProperties3 {  
      
     private  String name;  
     private  String location;  
     private  String mobile;  
     private  int  employCount;  
      
     //对应:com.kfit.company.firstName = lin  
     private  String firstName;  
      
     //对应:com.kfit.company.logo-path = d:/data/files/logo.png  
     private  String logoPath;  
      
     //对应:com.kfit.company.COMPANY_FULLNAME = xxxx科技公司  
     private  String companyFullname;  
      
     private  List<String> employs =  new  ArrayList<String>();  
      
      
     public  String getFirstName() {  
        return  firstName;  
     }  
     public  void  setFirstName(String firstName) {  
        this .firstName = firstName;  
     }  
     public  String getLogoPath() {  
        return  logoPath;  
     }  
     public  void  setLogoPath(String logoPath) {  
        this .logoPath = logoPath;  
     }  
     public  String getCompanyFullname() {  
        return  companyFullname;  
     }  
     public  void  setCompanyFullname(String companyFullname) {  
        this .companyFullname = companyFullname;  
     }  
     public  List<String> getEmploys() {  
        return  employs;  
     }  
     public  void  setEmploys(List<String> employs) {  
        this .employs = employs;  
     }  
     public  String getName() {  
        return  name;  
     }  
     public  void  setName(String name) {  
        this .name = name;  
     }  
     public  String getLocation() {  
        return  location;  
     }  
     public  void  setLocation(String location) {  
        this .location = location;  
     }  
     public  String getMobile() {  
        return  mobile;  
     }  
     public  void  setMobile(String mobile) {  
        this .mobile = mobile;  
     }  
     public  int  getEmployCount() {  
        return  employCount;  
     }  
     public  void  setEmployCount(intemployCount) {  
        this .employCount = employCount;  
     }  
     @Override  
     public  String toString() {  
        return  "CompanyProperties [name="  + name +  ", location="  + location +  ", mobile="  + mobile +  ", employCount="  
               + employCount +  ", firstName="  + firstName +  ", logoPath="  + logoPath +  ", companyFullname="  
               + companyFullname +  ", employs="  + employs +  "]" ;  
     }  
}

注意这里的代码和以上不一样的是类上的注解全没有了,之后我们在App.java启动类中或者其它的类也是可以的,使用@Bean的方式进行注入。

1
2
3
4
5
@Bean
     @ConfigurationProperties (prefix =  "com.kfit.company" )
     public  CompanyProperties3 companyProperties3(){
        returnnew CompanyProperties3();
     }

那么在其它的类中我们就使用@Autowired进行注入使用了,如下:

1
2
@Autowired  
private  CompanyProperties3 companyProperties3;


(9) 自定义结构;

       对于复杂的配置或嵌套的kv,我们可以编写自定义结构属性以更好的方式进行管理。

比如我们在application.properties文件中有如下信息:

1
2
3
4
5
6
7
com.kfit.employForzs.name =张三  
com.kfit.employForzs.age =  20  
com.kfit.employForzs.gender =男  
    
com.kfit.employForls.name =李四  
com.kfit.employForls.age =  25  
com.kfit.employForzs.gender =女

com.kfit.properties.CompanyEmployee的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package  com.kfit.properties;  
    
import  org.springframework.boot.context.properties.ConfigurationProperties;  
import  org.springframework.stereotype.Component;  
    
//prefix设置key的前缀;  
@ConfigurationProperties (prefix =  "com.kfit" )  
@Component  
public  class  CompanyEmployee {  
      
     private  CompanyEmployeeInfo employForzs;  
      
     private  CompanyEmployeeInfo employForls;  
      
     public  CompanyEmployeeInfo getEmployForzs() {  
        return  employForzs;  
     }  
    
     publicvoid setEmployForzs(CompanyEmployeeInfo employForzs) {  
        this .employForzs = employForzs;  
     }  
    
     public  CompanyEmployeeInfo getEmployForls() {  
        return  employForls;  
     }  
    
     publicvoid setEmployForls(CompanyEmployeeInfo employForls) {  
        this .employForls = employForls;  
     }  
    
     public  static  class  CompanyEmployeeInfo {  
        private  String name;  
        private  int  age;  
        private  String gender;  
        public  String getName() {  
            return  name;  
        }  
        publicvoid setName(String name) {  
            this .name = name;  
        }  
        public  int  getAge() {  
            return  age;  
        }  
        public  void  setAge(intage) {  
            this .age = age;  
        }  
        public  String getGender() {  
            returngender;  
        }  
        public  void  setGender(String gender) {  
            this .gender = gender;  
        }  
        @Override  
        public  String toString() {  
            return  "EmployForzs [name="  + name +  ", age="  + age +  ", gender="  + gender +  "]" ;  
        }  
     }  
    
     @Override  
     public  String toString() {  
        return  "CompanyEmployee [employForzs="  + employForzs +  ", employForls="  + employForls +  "]" ;  
     }  
}

观察以上的代码我们定义了一个内部静态类进行处理相同的属性,那么在外部类中定义两个变量进行接收application.properties文件中的配置信息。

之后在其它类就可以使用@Autowired进行注入使用了。


(10) 校验;

       当我们使用@ConfigurationProperties的时候,我们希望对一些参数进行校验,比如有些参数为空或者数字超出的限制就抛出异常信息,那么这个怎么操作呢?

在application.properties文件中加入:

1
com.kfit.company.url = http: //www.kfit.com


在CompanyProperties类中加入:

1
2
@URL
private  String url;

这里使用了@URL对url进行校验,如果是非法的url在启动的时候是会抛出异常信息的。

其中@URL对应的包路径为:org.hibernate.validator.constraints.URL

那么还有其它的什么校验器呢?看下文:

1
2
@Max (value =  99 )
private  int  employCount;

定义最大值只能是99,那么如果运行的话,显然就会报错了,因为之前我们配置的值是100,那么就会看到控制台抛出异常信息:

1
default  message [最大不能超过 99 ]

这里只是截取了一小部分异常信息,具体的异常信息是可以参数那个参数的设置有问题的。

既然有最大值就有最小值的配置:

1
2
3
@Max (value =  1000 )
@Min (value =  1 )
private  int  employCount;


接着往下看:

1
2
@NotNull
private  String name;


@NotNull说明name不能为null,如果为null就抛出异常。

接着往下看:

1
2
@NotEmpty
private  String location;

@NotEmpty不能为空,当没有定义key和key的值为空字符的时候都会抛出异常信息。


validation-api下包javax.validation.constraints下还有其它的校验器,大家可以根据需要自行学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值