Wechat official account: an excellent invalid. If you have any questions, please leave a message in the background. I’m not listening anyway.
preface
Recently, I have the idea of job-hopping, so I deliberately reviewed the relevant knowledge of SpringBoot and reviewed it in detail. Some of them, I think, are things that I’ve missed before, like the difference between @Value and @ConfigurationProperties.
How to use
Define two objects, a student object, corresponding to a teacher object, code as follows:
- @ConfigurationProperties
- Students in class
@Component
@ConfigurationProperties(prefix = "student") // Specify that the student property in the configuration file is bound to the bean
public class Student {
private String firstName;
private String lastName;
private Integer age;
private String gender;
private String city;
private Teacher teacher;
private List<String> hobbys;
private Map<String,Integer> scores;
// Note that toString and get and set methods must be overridden for testing purposes
}
Copy the code
- The teacher class
public class Teacher {
private String name;
private Integer age;
private String gender;
// Note that toString and get and set methods must be overridden for testing purposes
}
Copy the code
- The test class
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootValConproDemoApplicationTests {
@Autowired
private Student student;
@Test
public void contextLoads(a) {
// For convenience, please do not use system.out in your workSystem.out.println(student.toString()); }}Copy the code
- The output
Student{firstName='Chen', lastName='A good loser', age=24, gender='male', city='guangzhou', teacher=Teacher{name='eses', age=24, gender='woman'}, hobbys= {hobbys, scores={Java = scores100, Python=99, C=99}}
Copy the code
- @Value
${key} from an environment variable, a configuration file, or #{SpEL}
- Students in class
@Component
// @configurationProperties (prefix = "student") // Specifies that the student property in the configuration file is bound to the bean
public class Student {
/** *
*
*
* /
@Value("Chen") / / literal
private String firstName;
@Value("${student.lastName}") // Get values from environment variables, configuration files
private String lastName;
@Value(* 2 "# {12}") // #{SpEL}
private Integer age;
private String gender;
private String city;
private Teacher teacher;
private List<String> hobbys;
private Map<String,Integer> scores;
// Note that toString and get and set methods must be overridden for testing purposes
}
Copy the code
- The test results
Student{firstName='Chen', lastName='A good loser', age=24, gender='null', city='null', teacher=null, hobbys=null, scores=null}
Copy the code
The difference between
The difference between | @ConfigurationProperties | @Value |
---|---|---|
function | Batch injection of properties in the configuration file | Designate one by one |
Loose binding (loose syntax) | support | Does not support |
SpEL | Does not support | support |
JSR303 data verification | support | Does not support |
Complex type encapsulation | support | Does not support |
As you can see from the above table, there are five major differences between @ConfigurationProperties and @Value, the first of which is a functional difference demonstrated above. Let me show you the four differences that remain.
Loose grammar
Loose syntax means that an attribute can have multiple attribute names in the configuration file. For example, the firstName attribute in the student class can be called firstName, first-name, first_name, and first_name in the configuration file. This is supported by @ConfigurationProperties, not @Value. Let’s test this by using firstName as an example. The following code:
- @ConfigurationProperties
The student class’s firstName attribute is defined as first_name in the YML file:
student:
first_name: Chen The student class's firstName attribute is defined as first_name in the YML file
lastName: A good loser
age: 24
gender: male
city: Guangzhou
teacher: {name: eses,age: 24,gender: Female}
hobbys: [Basketball, badminton, Bing Bing Ball]
scores: {java: 100,Python: 99,C++: 99}
Copy the code
The student class:
@Component
@ConfigurationProperties(prefix = "student") // Specify that the student property in the configuration file is bound to the bean
public class Student {
/** *
*
*
* /
// @value (" Chen ") // literal
private String firstName;
// @value ("${student.lastname}") // Get the Value from the environment variable, configuration file
private String lastName;
//@Value("#{12*2}") // #{SpEL}
private Integer age;
private String gender;
private String city;
private Teacher teacher;
private List<String> hobbys;
private Map<String,Integer> scores;
// Note that toString and get and set methods must be overridden for testing purposes
}
Copy the code
Test results:
Student{firstName='Chen', lastName='A good loser', age=24, gender='male', city='guangzhou', teacher=Teacher{name='eses', age=24, gender='woman'}, hobbys= {hobbys, scores={Java = scores100, Python=99, C=99}}
Copy the code
- @Value
The student class:
@Component
// @configurationProperties (prefix = "student") // Specifies that the student property in the configuration file is bound to the bean
public class Student {
/** *
*
*
* /
// @value (" Chen ") // literal
@Value("${student.firstName}")
private String firstName;
// @value ("${student.lastname}") // Get the Value from the environment variable, configuration file
private String lastName;
//@Value("#{12*2}") // #{SpEL}
private Integer age;
private String gender;
private String city;
private Teacher teacher;
private List<String> hobbys;
private Map<String,Integer> scores;
// Note that toString and get and set methods must be overridden for testing purposes
}
Copy the code
Test result: Startup error, bean not found.
As you can see from the above two test results, with the @ConfigurationProperties annotation, the property in yML is named last_name and the property in the student class is lastName but still gets the value, while with the @Value annotation, Error with lastName. Prove that @ConfigurationProperties supports loose syntax, and @Value does not.
SpEL
SpEL use # {… } as the delimiter, all characters in braces will be considered SpEL, which facilitates dynamic assignment of bean properties.
- @Value
Here’s the code for the @value annotation, as described above:
@Value(* 2 "# {12}") // #{SpEL}
private Integer age;
Copy the code
Prove that @value supports SpEL expressions.
- @ConfigurationProperties
No effect is seen because # in YML is treated as a comment. So let’s create a new application.properties file. To annotate the contents of the YML file, we write the age property in the Properties file as follows:
student.age=#{12*2}
Copy the code
Open the @ConfigurationProperties annotation in the student class and comment the @Value annotation. The age attribute is incorrectly matched.
Note @ConfigurationProperties does not support SpEL
JSR303 data verification
- @Value
Add @length check:
@Component
@Validated
// @configurationProperties (prefix = "student") // Specifies that the student property in the configuration file is bound to the bean
public class Student {
/** *
*
*
* /
// @value (" Chen ") // literal
@Value("${student.first-name}")
@Length(min=5, max=20, message="Username must be between 5-20 in length")
private String firstName;
// @value ("${student.lastname}") // Get the Value from the environment variable, configuration file
private String lastName;
//@Value("#{12*2}") // #{SpEL}
private Integer age;
private String gender;
private String city;
private Teacher teacher;
private List<String> hobbys;
private Map<String,Integer> scores;
}
Copy the code
Yaml:
student:
first_name: Chen
Copy the code
Test results:
Student{firstName='Chen', lastName='null', age=null, gender='null', city='null', teacher=null, hobbys=null, scores=null}
Copy the code
In YAML, firstName is 1 in length. However, according to the verification rule, the attribute can still be obtained from 5 to 20, indicating that the verification does not take effect and @value does not support JSR303 data verification
- @ConfigurationProperties
The student class:
@Component
@Validated
@ConfigurationProperties(prefix = "student") // Specify that the student property in the configuration file is bound to the bean
public class Student {
/** *
*
*
* /
// @value (" Chen ") // literal
//@Value("${student.first-name}")
@Length(min=5, max=20, message="Username must be between 5-20 in length")
private String firstName;
// @value ("${student.lastname}") // Get the Value from the environment variable, configuration file
private String lastName;
//@Value("#{12*2}") // #{SpEL}
private Integer age;
private String gender;
private String city;
private Teacher teacher;
private List<String> hobbys;
private Map<String,Integer> scores;
}
Copy the code
Test result: An error is reported
[firstName],20.5]; defaultMessage [The length of the username must be in5-20Between]Copy the code
JSR303 data verification is supported.
Complex type encapsulation
Complex type encapsulation refers to the fact that @Value does not fetch a Value from an object or a map (e.g., the teacher class in the student class and scores map), for example:
@Component
//@Validated
// @configurationProperties (prefix = "student") // Specifies that the student property in the configuration file is bound to the bean
public class Student {
/** *
*
*
* /
// @value (" Chen ") // literal
//@Value("${student.first-name}")
// @length (min=5, Max =20, message=" user name must be between 5 and 20 ")
private String firstName;
// @value ("${student.lastname}") // Get the Value from the environment variable, configuration file
private String lastName;
//@Value("#{12*2}") // #{SpEL}
private Integer age;
private String gender;
private String city;
@Value("${student.teacher}")
private Teacher teacher;
private List<String> hobbys;
@Value("${student.scores}")
private Map<String,Integer> scores;
}
Copy the code
This is an error. The @ConfigurationProperties support complex type encapsulation, as demonstrated above by the @ConfigurationProperties and @Value usage methods. That is, yamL defines teacher and scores directly. @configurationProperties still gets a value.
How to choose?
-
If you just need to get a Value from a configuration file in some business logic, use @value; For example, if the student class now has an additional attribute called School, this attribute is the same for all students in the school, but my system will not be used in case of other schools. So we can just give a school property in YML and get it at sign Value. Of course, this is just a rough example, but for real development, the school property should be stored in the database.
-
If we wrote a javaBean specifically to map to configuration files, we would use @ConfigurationProperties directly.
The complete code
Github.com/turoDog/Dem…
If you think it is helpful, please give a Star and then go. Thank you very much.
After the language
If this article is of any help to you, please help to read it. Your good looks are my motivation to keep writing.
In addition, after paying attention to send 1024 can receive free learning materials.
For more information, see this article: Python, C++, Java, Linux, Go, front-end, algorithm sharing