This is the fifth day of my participation in the First Challenge 2022

Hello, hello, I am gray little ape, a super bug writing program ape!

This article is to share with you how to read properties from configuration files in SpringBoot.

We know that in the relatively large project development, are often modified properties are generally not in the code we write dead, but its definition in the configuration file, if change, after we can go directly to the configuration file modification, so in the project of springboot, how should we achieve this? Let’s show you how to read and use properties in a configuration file as an example.

Take the database configuration in YML as an example. The configuration file is as follows:

The configuration file

jdbc:
  driverClassName: com.mysql.jdbc.Driver
  url: JDBC: mysql: / / 127.0.0.1:3306 / test
  username: root
  password: root

Copy the code

(1) Use annotation @value mapping

The first method is to use the @Value annotation for mapping. This method is suitable for objects with few parameters. We can directly use the @Value annotation on the attributes of the object, and pass the corresponding attributes in the configuration file as ${}.

You also need to use the @Configuration annotation above the class to add it as a Configuration file for injection when starting the project. Examples are as follows:

@Configuration
public class JdbcProperties {
    @Value("${jdbc.driverClassName}")
    private String driverClassName;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
}

Copy the code

In this way, when we use the property value of the object, we can directly call the property of the object.

(2) Use the @ConfigurationProperties mapping

The second method is simpler than the first. Instead of using the @Value annotation on each field, you can simply use an @ConfigurationProperties annotation on the class, where the parameter is passed as the prefix of the parameter in the YML configuration file. But the effect is the same as the first one,

The @ConfigurationProperties annotation declares the current class to be a configurationread class

Prefix =” JDBC “: reads properties with a JDBC prefix

The attribute prefix in the configuration file is assigned to the field of the same name in the class

Examples are as follows:

@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
}

Copy the code

One thing to note when using this annotation is that the property name must be exactly the same as the field, and the class needs to provide setter methods for the field

But using the @ConfigurationProperties annotation alone doesn’t work. It doesn’t say anything about matching parameters and properties in the configuration file. It needs to be used in conjunction with other annotations that take effect when the project is started,

One way is to add an @Configuration annotation to the JdbcProperties class to identify it as a Configuration class, as follows:

@Configuration
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
    private String driverClassName;
    private String url;
    private String username;
    private String password;
}

Copy the code

Or there’s a second way: We also can be read using this configuration in the Spring class, read through @ EnableConfigurationProperties annotations can be specified configuration class object is loaded into the Spring container, that is to say, On top of other configuration class using a @ EnableConfigurationProperties annotations, to the parameters of the configuration file and JdbcProperties class attribute of the binding. This eliminates the need for the @Configuration annotation on the JdbcProperties class,

Examples are as follows:

@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {
    @Autowired
    private JdbcProperties prop;

    /** This method is not required@AutowiredThe JdbcProperties object */ is automatically injected by Springboot when the DataSource object is created
    @Bean
    public DataSource dataSource(a){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(prop.getDriverClassName());
        dataSource.setUrl(prop.getUrl());
        dataSource.setUsername(prop.getUsername());
        dataSource.setPassword(prop.getPassword());
        returndataSource; }}Copy the code

(3) Recommended use: The minimalist @bean with the @ConfigurationProperties annotation,

For my personal habit, I prefer to use the third method, which is the easiest to use and the most practical,

In a Configuration class with the @Configuration annotation, we can declare the @ConfigurationProperties(Prefix = “JDBC”) annotation directly on the @bean method we want to use, Springboot automatically assigns properties starting with prefix in the configuration file to fields of the same name of the class to which the object is to be created, provided that the class provides setter methods

The advantage of using this approach is that you do not make any additional annotation declarations on the bean. Put classes that need to be injected easily or bound to Configuration file parameters in a class annotated with @Configuration.

@Configuration
public class JdbcConfig {
    @Bean
    @ConfigurationProperties(prefix = "jdbc")
    public JdbcProperties jdbcProperties(a){
        return newJdbcProperties(); }}Copy the code

However, the above operations only inject the bean into the container, so other classes would still need to use the @AutoWired annotation on each object. Is there any way to declare automatic injection without using the @AutoWired annotation?

The @requiredargsConstructor annotation implements automatic injection

The @requiredargsConstructor annotation can be used instead of the @AutoWired annotation to implement automatic injection of object attributes,

Usage scenario: If you need to inject a lot of Mapper interfaces or other service interfaces, you can write a lot of @autoWired annotations. The code looks messy. Lombok provides one:

@RequiredArgsConstructor(onConstructor =@_(@Autowired))

Writing to a class can replace the @autoWired annotation. Note that final definitions are required for injection, or @notnull annotations are used

@RestController
@RequiredArgsConstructor
public class LoginTest {

// @Autowired
    private final LoginProperties loginProperties;

    @RequestMapping("/login01")
    public void loginTest01(a){
        System.out.println("Enter logAdd 01 method ~~~"); String language = loginProperties.getLanguage(); System.out.println(language); }}Copy the code

This avoids repeating @autoWired, but it is important to note that the object must be final,

To summarize, if you need to bind class attributes to parameters in a configuration file and inject them into a container, the third method and the @requiredargsconstructor annotation are recommended!!

This is how to implement the springBoot project to read configuration file parameters and automatic injection, if you have any questions, welcome to leave a message in the comment section.

I’m Grey Ape, and I’ll see you next time!