SpringBoot主配置和註解

m0_51302187發表於2020-10-16

SpringBoot主配置和註解

建議Springboot使用版本:2.1.13.RELEASE

applicatin.properties的優先順序比application.yml優先順序高,但是一般專案中不會同時出現這兩種配置檔案

yml配置檔案寫法

例子:

person是物件,maps是map集合,lists是list集合,student是物件,具體關係為:

package com.hui.pojo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@ConfigurationProperties(prefix = "person")
@Component
public class Person {

    private String name;
    private String age;
    private Date birth;
    private Map<String,Object> maps;
    private List<String> lists;
    private Student student;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<String> getLists() {
        return lists;
    }

    public void setLists(List<String> lists) {
        this.lists = lists;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public String toString() {
        return "Persion{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", student=" + student +
                '}';
    }
}
package com.hui.pojo;

public class Student {
    private String stuName;
    private String stuAge;

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public String getStuAge() {
        return stuAge;
    }

    public void setStuAge(String stuAge) {
        this.stuAge = stuAge;
    }
}

yml的配置:

person:
  name: zhangsan
  age: 18
  birth: 2017/04/21
  maps: {k1: v1,k2: v2}
  lists:
    - dog
    - cat
  student:
    name: lisi
    age: 14

其中map和list有兩種配置方式

第一種:

#map型別
maps:
  k1: v1
  k2: v2
#list型別
lists:
  - dog
  - cat

第二種行內設定:

#map型別
maps: {k1: v1,k2: v2}
#list型別
lists: [dog,cat]

配置檔案佔位符

無論是在application.properties還是yml.properties中,都可以使用以下兩種佔位符

第一種:隨機數佔位符

${random.value} # 隨機一串數,例如:821910b2a528f7ee35ea94fcc8682c01

${random.int}  # 隨機整數,例如:-198290765

${random.int(max)} # 隨機數小於max

${random.int(min,max)} # 隨機數介於min和max之間,大於等於min,小於max

${random.long} # 隨機長整型,例如:-7439395970807654149

${random.long(max)}

${random.long(min,max)}

${random.uuid} # 隨機uuid,例如:561ec89a-5441-4211-84de-8a3ebaacf2e0

例子如下:

#該person就是上文prefix指定的值
person:
  first-name: zhang${random.value}  #字串會和隨機數直接拼接
  age: ${random.int(1,10)}
  birth: 2017/04/21
  maps: {k1: v1,k2: v2}
  lists:
    - dog
    - cat
  student:
    stuName: lisi
    stuAge: 20

第二種:屬性配置佔位符

屬性配置佔位符比較簡單,舉例如下:

#該person就是上文prefix指定的值
person:
  first-name: zhang
  age: 19
  birth: 2017/04/21
  maps: {k1: v1,k2: v2}
  lists:
    - dog
    - cat
  student:
    stuName: ${person.first-name}# 結果:zhang三
    stuAge: ${person.age}                # 結果:19

註解

WEB相關注解

package com.hui.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@ResponseBody
@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello(){
        return "hello";
    }
}

@Controller:將檢視層註冊到Spring容器中

@ResponseBody:將方法返回值返回給瀏覽器,讓瀏覽器能夠顯示,也可以作用於方法上

@RequestMapping("/hello"):瀏覽器請求時的路徑

其中註解@RestController=@Controller+@ResponseBody,所以也可以寫成

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello(){
        return "hello";
    }
}

ConfigurationProperties註解

作用:將配置檔案(properties和yml)中配置的每一個屬性的值,對映到這個元件中

@ConfigurationProperties:告訴springboot將本類中的所有屬性和配置檔案中相關的配置進行繫結

  • prefix = “persion”:執行配置檔案中"person"下面的所有屬性一一對映

注意:只有這個元件是容器中的元件,才能使用容器提供的ConfigurationProperties註解功能

package com.hui.pojo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;


@ConfigurationProperties(prefix = "person")
@Component
public class Person {

    private String firstName;
    private String age;
    private Date birth;
    private Map<String,Object> maps;
    private List<String> lists;
    private Student student;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<String> getLists() {
        return lists;
    }

    public void setLists(List<String> lists) {
        this.lists = lists;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    @Override
    public String toString() {
        return "Person{" +
                "firstName='" + firstName + '\'' +
                ", age='" + age + '\'' +
                ", birth=" + birth +
                ", maps=" + maps +
                ", lists=" + lists +
                ", student=" + student +
                '}';
    }
}
package com.hui.pojo;

public class Student {
    private String stuName;
    private String stuAge;

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public String getStuAge() {
        return stuAge;
    }

    public void setStuAge(String stuAge) {
        this.stuAge = stuAge;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuAge='" + stuAge + '\'' +
                '}';
    }
}

yml配置檔案:application.yml(注意格式,格式出錯會報錯)

#該person就是上文prefix指定的值
person:
  #此處是鬆散繫結,雖然firstName=first-name,在鬆散繫結中-n相當於N
  first-name: zhang
  age: 19
  birth: 2017/04/21
  maps: {k1: v1,k2: v2}
  lists:
    - dog
    - cat
  student:
    stuName: lisi
    stuAge: 20

properties配置:application.properties

person.name=zhangsan
person.age=18
person.birth=2017/04/21
person.maps.k1=v1
person.maps.k2=v2
person.lists=dog,cat
person.student.stuName=lisi
person.student.stuAge=14

引入了註解@ConfigurationProperties後,可以加一個以下依賴(也可以不加):

<!--匯入配置檔案處理器,配置檔案進行繫結就會有提示-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

該依賴的作用是在寫好了一個pojo物件後,在配置檔案中寫裡面相應的屬性時,會有提示

在這裡插入圖片描述

Value註解

作用:賦值

使用方式:

  • Value=“字面量”:直接給賦值
  • Value="${key}": 從環境變數、配置檔案中獲取值
  • Value="#{SpEL}":可以使用SpEL表示式進行賦值
@Value("li")                //Value="字面量":直接給賦值
private String firstName;
@Value("${person.birth}")   //Value="${key}": 從環境變數、配置檔案中獲取值
private Date birth;
@Value("#{11*2}")           //Value="#{SpEL}":可以使用SpEL表示式進行賦值
private String age;

ConfigurationProperties和Value比較

@ConfigurationProperties@Value
功能批量注入配置檔案中的屬性一個個指定
鬆散繫結(鬆散語法)支援不支援
SpEL不支援支援
JSR303資料校驗支援不支援
複雜型別封裝支援不支援

鬆散繫結:

在配置檔案(properties和yml)中,以下3個寫法是相等的
person.firstName       標準格式
person.first-name      -n等效於N
person.first_name      _n等效於N

JSR303資料校驗:

參看文章《Validated註解使用.md》

PropertySource和ImportResource註解

@PropertySource:用於載入指定配置檔案

載入單個指定配置檔案:

@PropertySource(value = "classpath:person.properties")
@ConfigurationProperties(prefix = "person")
@Component
@Validated
public class Person {
    //todo...
}

如此載入的話,配置資訊就可以不寫在application.properties或者application.yml檔案中了,可以寫在person.properties中

#該person就是上文prefix指定的值
person.firstName=wang
person.age=19
person.birth=2017/04/21
person.maps.k1=v1
person.maps.k2=v2
person.lists=dog,cat
person.student.stuName=wangwu
person.student.stuAge=25

載入多個指定配置檔案:

@PropertySource(value = {"classpath:person.properties","classpath:student.properties"})
@ConfigurationProperties(prefix = "person")
@Component
@Validated
public class Person {
    //todo...
}

person.properties檔案

#該person就是上文prefix指定的值
person.firstName=wang
person.age=19
person.birth=2017/04/21
person.maps.k1=v1
person.maps.k2=v2
person.lists=dog,cat

student.properties檔案

person.student.stuName=wangwu
person.student.stuAge=25

@ImportResource:匯入spring的配置檔案,讓配置檔案裡面的內容生效

我們先在resources資料夾下寫一個bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="personMethod" class="com.hui.service.PersonService"></bean>

</beans>

再寫一個PersonService服務com.hui.service.PersonService

package com.hui.service;

public class PersonService {
    public String personMethod(){
        return "I am a person!";
    }
}

接下來開始測試:

第一種測試:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootdemoApplicationTests {
    
    @Test
    public void personMethodTest() {
        ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
        System.out.println(ac.containsBean("personMethod"));
        PersonService personService= (PersonService) ac.getBean("personMethod");
        System.out.println(personService.personMethod());
    }
}

列印結果為true和I am a person!,這說明我們在new ClassPathXmlApplicationContext(“bean.xml”)時便載入了spring容器,將personMethod存到到了容器中,此種獲取方法我們不需要使用ImportResource註解

第二種測試:

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootdemoApplicationTests {

    @Autowired
    ApplicationContext ac;

    @Test
    public void personMethodTest() {
        System.out.println(ac.containsBean("personMethod"));
    }
}

列印結果為false,這說明通過這種方法我們無法載入bean.xml檔案,這時我們如果還想載入bean.xml檔案,需要在springboot的啟動類上加上註解@ImportResource,並指定要匯入的檔案

@ImportResource(value = {"classpath:bean.xml"})
@SpringBootApplication
public class SpringbootdemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootdemoApplication.class, args);
    }

}

此時再執行測試類,便可以列印出true了

該註解在springboot中並不常用,因為springboot一般使用配置類,而不使用spring型別的xml檔案。配置類的使用參考spring中的《Spring的新註解.md》

測試方面註解

Springboot測試方面相關的註解如下:

com.hui.SpringbootgeneratorApplicationTests

package com.hui;

import com.hui.pojo.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootgeneratorApplicationTests {

    @Autowired
    private Person person;

    @Test
    public void contextLoads() {
        System.out.println(person.toString());
    }
}

Srpingboot的版本如果使用2.2.16.RELEASE,發現@Runwith報錯,使用2.1.13.RELEASE不報錯

Profile

用於多檔案的配置,可以使我們自由切換不同的springboot配置檔案,檔名是:application-{profile}.properties/yml

application.properties

對於application.properties的配置檔案,我們可以建立多個其它的配置檔案,例如有以下三個環境:

application.properties 預設環境

server.port=8080
# 通過配置該值來決定使用哪一個配置檔案
#spring.profiles.active=dev

application-dev.properties 開發環境

server.port=8081

applicatio-prod.properties 生產環境

server.port=8082

使用具體哪個環境,需要在application.properties 檔案中進行配置spring.profiles.active的值:

  • 如果不配置,預設使用application.properties配置檔案,
  • 如果配置``spring.profiles.active=dev,使用application-dev.properties配置檔案
  • 如果配置``spring.profiles.active=prod,使用application-prod.properties配置檔案

application.yml

對於application.yml,不需要配置多個檔案,yml支援多文件快方式,每個文件快用---隔開

server:
  port: 8083

# 通過這個配置決定啟用哪一個文件快,如果不配置,預設啟用第一個文件快
spring:
  profiles:
    active: prod

---
server:
  port: 8084

# 如果使用多文件快,這一步必須配置,否則多文件快不會生效,會造成預設啟用最後一個文件快
spring:
  profiles: dev

---
server:
  port: 8085

# 如果使用多文件快,這一步必須配置,否則多文件快不會生效,會造成預設啟用最後一個文件快
spring:
  profiles: prod

注意:如果使用多文件快,除了第一個文件快外的其他文件快都要配置上spring-profiles,否則會被預設啟用最後一個文件快

相關文章