Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the pose of @ ConfigurationProperties annotation?

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces what the pose of @ ConfigurationProperties annotation is, and the content is very detailed. Interested friends can use it for reference. I hope it will be helpful to you.

When writing project code, we require more flexible configuration and better modular integration. In the Spring Boot project, in order to meet the above requirements, we configure a large number of parameters in application.properties or application.yml files. Through the @ ConfigurationProperties annotation, we can easily obtain these parameter values.

Use @ ConfigurationProperties to configure the module

Suppose we are building a module to send mail. In local testing, we don't want the module to actually send mail, so we need a parameter to "turn on" the disable function. In addition, we want to configure a default theme for these messages, so that when we check our email inbox, we can quickly tell that this is a test message by the subject of the email.

Create these parameters in the application.properties file:

We can access these properties using the @ Value annotation or using Spring Environment bean, which is sometimes cumbersome in injection configuration. We will use a more secure way (@ ConfigurationProperties) to get these properties

The basic use of @ ConfigurationProperties is simple: we provide a class with fields for each external property to be captured. Please note the following points:

The prefix defines which external properties will be bound to the fields of the class

According to Spring Boot's loose binding rules, the property name of a class must match the name of an external property.

We can simply initialize a field with a value to define a default value.

The class itself can be private to the package

The field of a class must have a public setter method

Spring loose binding rules (relaxed binding)

Spring uses some loose rules for binding properties. Therefore, the following variants are bound to the hostName attribute:

If we inject bean of type MailModuleProperties into another bean, the bean can now access the values of those external configuration parameters in a type-safe manner.

However, we still need to let Spring know that our @ ConfigurationProperties class exists in order to load it into the application context (the interview doesn't know the difference between BeanFactory and ApplicationContext?)

Activate @ ConfigurationProperties

For Spring Boot, create a bean of type MailModuleProperties, which we can add to the application context in the following ways

First, we can have Component Scan scan to the

Obviously, it will only take effect if the package in which the class resides is scanned by the Spring @ ComponentScan annotation, which scans all package structures under the main application class by default

We can also achieve the same effect through the Java Configuration feature of Spring:

As long as the MailModuleConfiguration class is scanned by the Spring Boot application, we can access the MailModuleProperties bean in the application context

We can also use the @ EnableConfigurationProperties annotation to make our class known to Spring Boot. In this annotation, we actually use @ Import (EnableConfigurationPropertiesImportSelector.class) to implement it. You can take a look at it.

What's the best way to activate a @ ConfigurationProperties class?

All the above methods are equally effective. However, I suggest modularizing your application and having each module provide its own @ ConfigurationProperties class, providing only the properties it needs, as we did for the mail module in the code above. This makes it easy to ReFactor attributes in a module without affecting other modules.

Therefore, I do not recommend using @ EnableConfigurationProperties on the application class itself, as shown in many other tutorials, on the module-specific @ Configuration class, which can also use the private visibility of the package to hide properties from the rest of the application.

Properties that cannot be converted

What happens if the property we define on the application.properties attribute cannot be parsed correctly? If we provide a value of 'foo': for a property that should have a Boolean value

By default, Spring Boot will fail to start and throw an exception:

Failed to bind properties under 'myapp.mail.enabled' to java.lang.Boolean: Property: myapp.mail.enabled Value: foo Origin: class path resource [application.properties]: 1:20 Reason: failed to convert java.lang.String to java.lang.Boolean

When we configure the wrong value for the property and do not want the Spring Boot application to fail to start, we can set the ignoreInvalidFields property to true (default is false)

In this way, Spring Boot will set the enabled field to the default value we set in the Java code. If we do not set the default value, enabled will be null, because the wrapper class Boolean of boolean is defined here

Unknown attribute

Contrary to the above, what happens if we provide properties in the application.properties file that the MailModuleProperties class doesn't know about?

By default, Spring Boot ignores properties that cannot be bound to fields of the @ ConfigurationProperties class

However, when there is a property in the configuration file that is not actually bound to the @ ConfigurationProperties class, we may want the startup to fail. Maybe we have used this configuration property before, but it has been deleted, in which case we want to be triggered to tell us to manually remove this property from application.properties

To do this, we just need to set the ignoreUnknownFields property to false (default is true)

Now, when the application starts, the console will give us abnormal information.

Binding to target [Bindable@cf65451 type = com.example.configurationproperties.properties.MailModuleProperties, value= 'provided', annotations = array [@ org.springframework.boot.context.properties.ConfigurationProperties (value=myapp.mail, prefix=myapp.mail, ignoreInvalidFields=false, ignoreUnknownFields=false)]] failed: Property: myapp.mail.unknown-property Value: foo Origin: class path resource [application.properties]: 3:29 Reason: The elements [myapp.mail.unknown-property] were left unbound.

Deprecation warning ⚠️ (Deprecation Warning) ignoreUnknownFields will be marked as deprecated in future versions of Spring Boot, because we may have two classes with @ ConfigurationProperties bound to the same namespace (namespace). One class may know a property while the other class does not, which will cause startup failure.

Check @ ConfigurationProperties at startup

If we want the configuration parameters to be valid when passed into the application, we can add the bean validation annotation to the field and the @ Validated annotation to the class

If we forget to set the enabled property in the application.properties file and set defaultSubject to empty

When the application starts, we will get BindValidationException

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'myapp.mail' to com.example.configurationproperties.properties.MailModuleProperties failed: Property: myapp.mail.enabled Value: null Reason: must not be null Property: myapp.mail.defaultSubject Value: null Reason: must not be empty

Of course, these default verification annotations can not meet your verification requirements, we can also customize the annotations

If your validation logic is special, we can implement a method and mark it with @ PostConstruct. If the validation fails, the method can throw an exception. For @ PostConstruct, you can check the life cycle of Spring Bean. Where do I come from?

Complex attribute type

In most cases, the parameters we pass to the application are basic strings or numbers. However, sometimes we need to pass data types such as List

List and Set

If we provide a list of SMTP services for the mail module, we can add this attribute to the MailModuleProperties class

There are two ways for Spring Boot to automatically populate the list property

Application.properties

Write as an array in an application.properties file

Application.yml

YAML itself supports list types, so you can add:

Set collections are also configured in this way and are no longer rewritten. In addition, YAML is a better way to read and have a clear hierarchy, so it is more recommended to use this way to configure data in practical applications.

Duration

Spring Boot has built-in support for parsing durations (duration) from configuration parameters, which is clearly explained on the official website.

We can configure either millisecond values or text with units:

It is clearly stated on the official website that duration is configured not to write units. By default, units are specified in milliseconds, or we can specify units through @ DurationUnit:

The common units are as follows:

Ns for nanoseconds (nanosecond)

Us for microseconds (microseconds)

Ms for milliseconds (milliseconds)

S for seconds (seconds)

M for minutes (min)

H for hours (hour)

D for days (God)

DataSize

As with Duration, the default unit is byte (bytes), which can be specified in @ DataSizeUnit units:

Add configuration

However, when I test it, the printed results are displayed in B (bytes).

Common units are as follows:

B for bytes

KB for kilobytes

MB for megabytes

GB for gigabytes

TB for terabytes

Custom type

In some cases, we want to parse the configuration parameters to our custom object type, assuming that we set the maximum package weight:

Add Weight attribute to MailModuleProperties

We can imitate DataSize and Duration to create our own converter (converter).

Register it in the Spring Boot context

The @ ConfigurationPropertiesBinding annotation is to let Spring Boot know that the converter is used for data binding

Use Spring Boot Configuration Processor to complete automatic completion

We add dependencies to the project:

Maven

Gradle

After re-build the project, configuration processor creates a JSON file for us:

This way, there will be an automatic reminder when we write the configuration in application.properties and application.yml:

Tag configuration attribute is Deprecated

Configuration processor allows us to mark an attribute as deprecated

We can mark the field as deprecated by adding the @ DeprecatedConfigurationProperty annotation to the getter method of the field, re-build the project and see what happens to the JSON file.

When we rewrite the configuration file, we have given a clear deprecated hint:

Summary

Spring Boot's @ ConfigurationProperties annotation is very powerful when binding type-safe Java Bean, and we can get a more friendly programming approach with its annotation properties and @ DeprecatedConfigurationProperty annotation, while making our configuration more modular.

Additional instructions

Do you think the @ ConfigurationProperties annotation meets all our needs? In fact, the Spring website clearly gives a comparison between this note and the @ Value note:

If we use SpEL expressions, we can only choose @ Value annotations

In addition, when I read the RabbitMQ source code before, I found that the RabbitProperties class makes full use of the @ ConfigurationProperties annotation feature:

Deprecated

Duration

Enum

Nested attribut

I feel that I have the benefit of hindsight. I have been thinking about why I had to read and recite classics such as ancient poetry and classical Chinese when I was a child, because writing articles in this way can easily and skillfully quote classics. The same is true of technology. The source code of various frameworks is the ancient poems and classical Chinese of our student days. We should read more, and even recite programming ideas, so that we can write more and more elegant code.

With regard to the use of the @ ConfigurationProperties annotation, RabbitMQ Github source code is recommended here. Just look at this class and know how to make full use of this annotation.

So much for sharing about the pose of the @ ConfigurationProperties annotation. I hope the above content can be helpful to you and learn more. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report