Before talking about SpringBoot to get configuration files we need to have an overall understanding of the SpringBoot project, how to create the SpringBoot project, project structure and so on knowledge points, I am not here to tell about, did not learn partners can find some information on the Internet to learn, very simple.

Let’s start today’s lecture.

SpringBoot global configuration file loading sequence

In SpringBoot, global configuration files are available in two different formats: properties and YML. In fact, there is not much difference between the two formats of the file, the use of personal habits to line, we use yML file.

First, when we create a SpringBoot project, by default we create an application.properties file in the Resources directory where we can configure the project. But in SpringBoot, application.properties can be stored in the following locations:

File :./config/ Under the config folder in the project root directory

File :./ In the project root directory

Classpath :/config/ In the config folder of the classpath

Classpath :/ In the classpath

The loading sequence of files is: config under the root directory, then config under the root directory, then config under the classpath directory, and finally classpath.

A configuration with a higher priority overrides a configuration with a lower priority.

If: Port 8084 is defined in the config directory of the root directory, port 8083 is defined in the root directory, port 8082 is defined in the config directory of the classpath path, port 8081 is defined in the classpath path. Finally, port 8084 is started. High priority overrides low priority.

Note: It is not that the higher priority is loaded and the lower priority is not loaded, but that SpringBoot loads the master configuration file from all four locations, and can have a cross-configuration effect.

In addition, we can change the default configuration file location via spring.config.location.

Once the project is packaged, we can specify the new location of the configuration file when starting the project using command-line arguments. Specify that these default loaded profiles work together to form a complementary configuration.

In the G drive directory, create an application.yml file and define port 8085

Java -jar spring-boot-config-0.0.1- snapshot. jar –spring.config.location=G:/application.yml

External configuration loading sequence

  1. Command line arguments

    Java -jar spring-boot-config-0.0.1- snapshot. jar –server.port=8087

—- search outside jar and inside jar:

2. Preferentially load profiles

Application -{profile}. Properties or application. Yml (with spring.profile) configuration file outside the JAR package

Place the jar package in a directory and create a new file named application.yml in that folder

The port is 8082, the access path is /boot, and the command line directly starts the project. Java jar – spring – the boot – config – 0.0.1 – the SNAPSHOT. Jar — application. Yml

Before talking about configuration files, LET me talk about the format of writing configuration information in YML files

The basic data type (eight basic data types) can be written in k: V format

For example, if I define an attribute (age) of type int in an entity class (Person), it will be written in the following format in the YML file

person:
  age: 20
Copy the code

Entity class objects (Person),Map,k: v write the relationship between the object’s properties and values on the next line, note the indentation

person:
  userName: zhans
  age: 20
Copy the code
# Another way to write inline
person: {userName: zhans.age: 20}  
Copy the code

List, array writing, notice – after the space

pets:
 - cat
 - dog
 - pig
Copy the code
# Another way to write inline
pets:{cat,dog,pi}
Copy the code

How SpringBoot obtains the configuration file

**@Value **

To create a configuration class, we omit setters and getters for space reasons, but in practice this is necessary, otherwise the injection will not succeed. @Component means to inject the current configuration class into the Spring container.

@Component
public class PersonConfig {

    @Value("${person.userName}")
    private String userName;
    @Value("${person.age}")
    private int age;
    
}
Copy the code

Add the following configuration to the master configuration file (application.yml)

server:
  port: 8081
person:
  userName: hello
  age: 20
Copy the code

The test class:

@RestController
public class PersonController {
    @Autowired
    private Person person;

    @RequestMapping(value = "/get",method = RequestMethod.GET)
    public String findPerson() {return "Name:"+person.getUserName()+"Age:"+person.getAge(); }}Copy the code

Start the project, visit the address http://localhost:8080/get run results:

Name: Hello Age: 20Copy the code

So, we can get the specified configuration item in the global configuration file by @value (${key}).

@ConfigurationProperties

If we need to fetch a lot of configuration items, we need to fetch them one by one via @value, which is obviously a bit of a hassle. So we can use @ConfigurationProperties.

All properties of the class labeled @ConfigurationProperties are bound to the relevant configuration items in the configuration file. After binding, we can access property values in the global configuration file through this class.

Example code is as follows:

  1. Add the following configuration to the master configuration file
user:
  username: admin
  password: 123456
  map: {k1: v1,k2: v2}
  list:
    - cat
    - dog
  person:
    userName: hello
    age: 20
  objects:
    - aaa
    - bbb
    - ccc
Copy the code
  1. The setter, getter, and toString methods are omitted for space reasons, but they are required in real development, otherwise injection will not succeed.
@Component
@ConfigurationProperties(prefix = "user")
public class User {
    private String  username;
    private String password;
    private Map<String,String> map;
    private Person person;
    private List<String> list;
    private Object[] objects;

}

Copy the code

Here @ConfigurationProperties has a prefix parameter, which is used to specify the prefix of the configuration item in the configuration file, namely user.

The test class

@RestController
public class PersonController {
    @Autowired
    private Person person;
    @RequestMapping(value = "/findUser",method = RequestMethod.GET)
    public String findUser() {returnuser.toString(); }}Copy the code

We at http://localhost:8081/findUser page, the page shows that we in the yml file configuration information.

User{username='admin', password='123456', map={k1=v1, k2=v2}, person=com.zfcoding.config.Person@93471e6, list=[cat, dog], objects=[aaa, bbb, ccc]}
Copy the code

What’s the difference between the two approaches?

@ConfigurationProperties @Value
function Batch injection of configuration file properties One by one
Loosely bound support Does not support
JSR303 data verification support Does not support
Complex data encapsulation support Not supported (Map)

Loosely bound,username can be represented by user-name to get the value

JSR303 data verification. If @Value is used to obtain the global configuration file attributes, the @ validation file does not take effect.

The @propertysource annotation loads the specified configuration file.

@propertysource (value = “”) specifies which configuration file under the classpath to load to inject the value

The setter, getter, and toString methods are omitted for space reasons, but they are required in real development, otherwise injection will not succeed.

@Component
@PropertySource( "classpath:student.properties")
@ConfigurationProperties(prefix = "student")
public class Student {

    private String sname;
}
Copy the code

Add the following configuration to the student.properties file

student.sname=admin
Copy the code

The test class

@SpringBootTest
class SpringbootExampleApplicationTests {
    @Autowired
    private DogConfig dogConfig;
    @Test
    void contextLoads() {
       System.out.println("Injected object:"+dogConfig.getName()); }}Copy the code

Running results:

Student{sname='admin'}
Copy the code

ImportResource Imports the Spring configuration file

The @importResource annotation is used to import the Spring configuration file. If the Spring configuration file “bean.xml”, To validate the contents of the configuration file, you can usually tag @ImportResource on the @SpringBootApplication startup class.

For example, if we inject PersonService into the Spring container and use the Spring configuration file as an example:

public class PersonService {
}
Copy the code
@ImportResource("classpath:bean.xml") @SpringBootApplication public class SpringBootConfigApplication { public static void main(String[] args) { SpringApplication.run(SpringBootConfigApplication.class, args); }}Copy the code

Spring configuration file: 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="personService" class="com.zfcoding.service.PersonService"></bean>
</beans>
Copy the code

Test cases:

@SpringBootTest
class SpringBootConfigApplicationTests {
    @Autowired
    private PersonService personSerivcer;
    @Test
    void contextLoads() {
        System.out.println("Injected object:"+personSerivcer); }}Copy the code

Results of the run:

The injected object: com. Zfcoding. Service. 5 b84f14 PersonService @Copy the code

The Spring bean configuration implementation, but SpringBoot recommended that we use annotations development, so SpringBoot annotations how to achieve bean injection?

@configuration: indicates that the current class is a Configuration class, which is the replacement for the spring Configuration file mentioned above.

The @bean adds the method return value to the container, where the default ID of the component is the method name

@Configuration
public class MyConfig {
    @Bean
    public PersonSerivcer personSerivcer() {returnnew PersonSerivcer(); }}Copy the code

This makes it possible to implement annotations instead of configuration files in Spring.

SpringBoot Profile

Let’s take yML files as an example

Yml (application-dev.yml, application-prod.yml), The configuration of the file application.yml is used by default

1, If we want to use the application-dev.yml global configuration file, specify it in application-.

Configuration examples:

Add the following configuration to the application.yml configuration file

spring:
  profiles:
    active: dev
Copy the code

Add the following configuration l to the application-dev.ym configuration file

server:
  port: 8080
# project path for application accessServlet: context-path: /boot person: usernameCopy the code

2. Yml supports multiple document express

Then add the following configuration L to the application-dev.ym configuration file

spring: profiles: active: prod --- server: port: 8080 servlet: context-path: /zf spring: profiles: dev --- person: UserName: aha Server: port: 8081 Servlet: Context-path: /boot Spring: Profiles: prodCopy the code

3, the Program of the arguments

Configure parameters in Program Arguments

–spring.profiles.active=dev

4. Virtual machine mode

Use the command -dspring.profiles. active=prod under VM options

Four, summary

In real development we would use the @ConfigurationProperties annotation if we wanted to take a bunch of configuration items, or the @Value annotation if we just injected one property,

The @propertysource annotation loads the specified configuration file, and the @importResource import the Spring configuration file (annotations can be used here instead).

Afterword.

Because my ability is limited, if the article has the wrong place, please point out, exchange study together. Today and everyone here, like my little friends, move your little hands dot attention.

Welcome everyone to pay attention to my public number: FU chat programming, long-term update Java various technical articles.