mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Document constructor binding
Closes gh-8762
This commit is contained in:
parent
de21d71e20
commit
d2164a1ca3
@ -894,7 +894,17 @@ Using the `@Value("${property}")` annotation to inject configuration properties
|
||||
sometimes be cumbersome, especially if you are working with multiple properties or your
|
||||
data is hierarchical in nature. Spring Boot provides an alternative method of working
|
||||
with properties that lets strongly typed beans govern and validate the configuration of
|
||||
your application, as shown in the following example:
|
||||
your application.
|
||||
|
||||
TIP: See also the <<boot-features-external-config-vs-value,differences between `@Value`
|
||||
and type-safe configuration properties>>.
|
||||
|
||||
|
||||
|
||||
[[boot-features-external-config-java-bean-binding]]
|
||||
==== JavaBean properties binding
|
||||
It is possible to bind a bean declaring standard JavaBean properties as shown in the
|
||||
following example:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@ -958,13 +968,13 @@ The preceding POJO defines the following properties:
|
||||
the name of the property. In particular, the return type is not used at all there and
|
||||
could have been `SecurityProperties`.
|
||||
* `acme.security.password`.
|
||||
* `acme.security.roles`, with a collection of `String`.
|
||||
* `acme.security.roles`, with a collection of `String` that defaults to `USER`.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Getters and setters are usually mandatory, since binding is through standard Java Beans
|
||||
property descriptors, just like in Spring MVC. A setter may be omitted in the following
|
||||
cases:
|
||||
Such arrangement relies on a default empty constructor and getters and setters are usually
|
||||
mandatory, since binding is through standard Java Beans property descriptors, just like in
|
||||
Spring MVC. A setter may be omitted in the following cases:
|
||||
|
||||
* Maps, as long as they are initialized, need a getter but not necessarily a setter,
|
||||
since they can be mutated by the binder.
|
||||
@ -984,11 +994,84 @@ Finally, only standard Java Bean properties are considered and binding on static
|
||||
properties is not supported.
|
||||
====
|
||||
|
||||
TIP: See also the <<boot-features-external-config-vs-value,differences between `@Value`
|
||||
and `@ConfigurationProperties`>>.
|
||||
|
||||
You also need to list the properties classes to register in the
|
||||
`@EnableConfigurationProperties` annotation, as shown in the following example:
|
||||
|
||||
[[boot-features-external-config-constructor-binding]]
|
||||
==== Constructor binding
|
||||
The example in the previous section can be rewritten in an immutable fashion as shown in
|
||||
the following example:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
package com.example;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertyDefaultValue;
|
||||
|
||||
@ConfigurationProperties("acme")
|
||||
public class AcmeProperties {
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
private final InetAddress remoteAddress;
|
||||
|
||||
private final Security security;
|
||||
|
||||
public AcmeProperties(boolean enabled, InetAddress remoteAddress, Security security) {
|
||||
this.enabled = enabled;
|
||||
this.remoteAddress = remoteAddress;
|
||||
this.security = security;
|
||||
}
|
||||
|
||||
public boolean isEnabled() { ... }
|
||||
|
||||
public InetAddress getRemoteAddress() { ... }
|
||||
|
||||
public Security getSecurity() { ... }
|
||||
|
||||
public static class Security {
|
||||
|
||||
private final String username;
|
||||
|
||||
private final String password;
|
||||
|
||||
private final List<String> roles;
|
||||
|
||||
public Security(String username, String password,
|
||||
@ConfigurationPropertyDefaultValue("USER") List<String> roles) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public String getUsername() { ... }
|
||||
|
||||
public String getPassword() { ... }
|
||||
|
||||
public List<String> getRoles() { ... }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
In this setup one, and only one constructor must be defined with the list of properties
|
||||
that you wish to bind and not other properties than the ones in the constructor are bound.
|
||||
|
||||
Default values can be specified using `@ConfigurationPropertyDefaultValue` and the same
|
||||
conversion service will be applied to coerce the `String` value to the target type of a
|
||||
missing property.
|
||||
|
||||
|
||||
|
||||
[[boot-features-external-config-enabling]]
|
||||
==== Enabling `@ConfigurationProperties`-annotated types
|
||||
Spring Boot provides an infrastructure to bind such types and register them as beans
|
||||
automatically. Any `@Configuration` class can specify the list of types to process as
|
||||
shown in the following example:
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@ -1006,15 +1089,19 @@ specified in the `@ConfigurationProperties` annotation and `<fqn>` is the fully
|
||||
name of the bean. If the annotation does not provide any prefix, only the fully qualified
|
||||
name of the bean is used.
|
||||
|
||||
The bean name in the example above is `acme-com.example.AcmeProperties`.
|
||||
The bean name in the examples above is `acme-com.example.AcmeProperties`.
|
||||
====
|
||||
|
||||
The preceding configuration creates a regular bean for `AcmeProperties`. We recommend that
|
||||
`@ConfigurationProperties` only deal with the environment and, in particular, does not
|
||||
inject other beans from the context. Keep in mind that the
|
||||
`@EnableConfigurationProperties` annotation is _also_ automatically applied to your
|
||||
project so that any _existing_ bean annotated with `@ConfigurationProperties` is
|
||||
configured from the `Environment`. Instead of annotating `MyConfiguration` with
|
||||
We recommend that `@ConfigurationProperties` only deal with the environment and, in
|
||||
particular, does not inject other beans from the context. In particular, it is not
|
||||
possible to inject other beans using the constructor as this would trigger the constructor
|
||||
binder that only deals with the environment.
|
||||
|
||||
For corner cases, setter injection can be used or any of the `*Aware` interfaces provided
|
||||
by the framework (such as `EnvironmentAware` if you need access to the `Environment`).
|
||||
|
||||
If you find using `@EnableConfigurationProperties` tedious, you can also declare a bean
|
||||
yourself. For instance, instead of annotating `MyConfiguration` with
|
||||
`@EnableConfigurationProperties(AcmeProperties.class)`, you could make `AcmeProperties`
|
||||
a bean, as shown in the following example:
|
||||
|
||||
@ -1024,11 +1111,21 @@ a bean, as shown in the following example:
|
||||
@ConfigurationProperties(prefix="acme")
|
||||
public class AcmeProperties {
|
||||
|
||||
// ... see the preceding example
|
||||
private boolean enabled;
|
||||
|
||||
private InetAddress remoteAddress;
|
||||
|
||||
private final Security security = new Security();
|
||||
|
||||
// ... see the preceding JavaBean properties binding example
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[boot-features-external-config-using]]
|
||||
==== Using `@ConfigurationProperties`-annotated types
|
||||
This style of configuration works particularly well with the `SpringApplication` external
|
||||
YAML configuration, as shown in the following example:
|
||||
|
||||
@ -1097,8 +1194,8 @@ its bean registration, as shown in the following example:
|
||||
}
|
||||
----
|
||||
|
||||
Any property defined with the `another` prefix is mapped onto that `AnotherComponent` bean
|
||||
in manner similar to the preceding `AcmeProperties` example.
|
||||
Any JavaBean property defined with the `another` prefix is mapped onto that
|
||||
`AnotherComponent` bean in manner similar to the preceding `AcmeProperties` example.
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user