Abstract: In the development of large projects, more often modified properties we are generally not in the code to write dead, but will define it in the configuration file, then if modified, we can directly go to the configuration file to modify, so in the SpringBoot project, we should how to achieve this?
This article is shared by Huawei Cloud community “SpringBoot Reads properties in configuration files and Implements Automatic Injection”, written by Grey Xiaoape.
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: rootCopy 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 in the form of ${}
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 simply use an @ConfigurationProperties annotation on the class. The parameters passed in are prefixes to the parameters in the YML configuration file, but the effect is the same
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 will take effect when the project is launched
One way is to add an @Configuration annotation to the JdbcProperties class, identifying 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 does not require @autowired to inject fields, nor does it require constructor injection. @bean Public DataSource DataSource (){DruidDataSource DataSource = new DruidDataSource(); dataSource.setDriverClassName(prop.getDriverClassName()); dataSource.setUrl(prop.getUrl()); dataSource.setUsername(prop.getUsername()); dataSource.setPassword(prop.getPassword()); return dataSource; }}Copy the code
(3) Recommended use: The minimalist @bean with the @ConfigurationProperties annotation,
For my personal habits, 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(){ return new JdbcProperties(); }}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(){system.out.println (" enter loginTest01 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!!
Click to follow, the first time to learn about Huawei cloud fresh technology ~