Skip to content

Commit 1af43d7

Browse files
committed
Rework @value documentation
See gh-23052
1 parent 44a00b5 commit 1af43d7

File tree

1 file changed

+63
-119
lines changed

1 file changed

+63
-119
lines changed

src/docs/asciidoc/core/core-beans.adoc

Lines changed: 63 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -5246,196 +5246,140 @@ named "customerPreferenceDao" and then falls back to a primary type match for th
52465246
[[beans-value-annotations]]
52475247
=== Using `@Value`
52485248

5249-
You can use `@Value` annotation to inject a default value to a constructor parameter, as the following example shows:
5249+
`@Value` is typically used to inject externalized properties:
52505250

52515251
[source,java,indent=0]
52525252
[subs="verbatim,quotes"]
52535253
----
5254+
@Component
52545255
public class MovieRecommender {
52555256
5256-
private final String algorithm;
5257+
private final String catalog;
52575258
5258-
public MovieRecommender(@Value("myRecommendationAlgorithm") String algorithm){
5259-
this.algorithm = algorithm;
5259+
public MovieRecommender(@Value("${catalog.name}") String catalog) {
5260+
this.catalog = catalog;
52605261
}
52615262
}
52625263
----
52635264

5264-
You can also apply the `@Value` annotation to fields, as the following example shows:
5265-
5266-
[source,java,indent=0]
5267-
[subs="verbatim,quotes"]
5268-
----
5269-
public class MovieRecommender {
5270-
5271-
@Value("myAlgorithm")
5272-
private String algorithm;
5273-
}
5274-
----
5275-
5276-
5277-
Built-in converter support provided by Spring allows simple type conversion to be automatically handled, as the following example shows:
5278-
5279-
5265+
With the following configuration:
52805266
[source,java,indent=0]
52815267
[subs="verbatim,quotes"]
52825268
----
5283-
public class MovieRecommender {
5284-
5285-
private final Integer depth;
5286-
5287-
public MovieRecommender(@Value("2") Integer depth){
5288-
this.depth = depth;
5289-
}
5290-
}
5269+
@Configuration
5270+
@PropertySource("classpath:application.properties")
5271+
public class AppConfig { }
52915272
----
52925273

5293-
As the annotation java type does not allow non constant value such as null, you can also safely use primitive type parameter:
5294-
5274+
And the following `application.properties` file:
52955275
[source,java,indent=0]
52965276
[subs="verbatim,quotes"]
52975277
----
5298-
public class MovieRecommender {
5299-
5300-
private final int depth;
5301-
5302-
public MovieRecommender(@Value("2") int depth){
5303-
this.depth = depth;
5304-
}
5305-
}
5306-
----
5307-
5308-
Multiple comma separated values parameter can be automatically converted to String array without extra effort:
5309-
5310-
[source,java,indent=0]
5311-
[subs="verbatim,quotes"]
5278+
catalog.name=MovieCatalog
53125279
----
5313-
public class MovieRecommender {
53145280

5315-
private final String[] catalogs;
5281+
In that case, the `catalog` parameter and field will be equal to the `MovieCatalog` value.
53165282

5317-
public MovieRecommender(@Value("catalogA,catalogB") String[] catalogs){
5318-
this.catalogs = catalogs;
5319-
}
5320-
}
5321-
----
5322-
5323-
Spring BeanPostProcessor uses ConversionService instance behind the scene to handle the process from converting
5324-
`@Value` value to the target type.
5325-
If you want to provide conversion support for your own custom type, you can provide your own ConversionService bean instance as the following example shows:
5283+
A default lenient embedded value resolver is provided by Spring. It will try to resolve the
5284+
property value and if it cannot be resolved, the property name (for example `${catalog.name}`)
5285+
will be injected as the value. If you want to maintain strict control over non existent
5286+
values, you should declare a `PropertySourcesPlaceholderConfigurer` bean, as the following
5287+
example shows:
53265288

53275289
[source,java,indent=0]
53285290
[subs="verbatim,quotes"]
53295291
----
5330-
@Configuration
5331-
public class MyConfig {
5292+
@Configuration
5293+
public class AppConfig {
53325294
5333-
@Bean
5334-
public static ConversionService conversionService() {
5335-
DefaultFormattingConversionService defaultFormattingConversionService = new DefaultFormattingConversionService();
5336-
defaultFormattingConversionService.addConverter(new MyCustomConverter());
5337-
return defaultFormattingConversionService;
5295+
@Bean
5296+
public PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
5297+
return new PropertySourcesPlaceholderConfigurer();
5298+
}
53385299
}
5339-
}
53405300
----
53415301

5342-
SpEL built-in support allows dynamically computed `@Value` at runtime as in the following example shows:
5343-
5344-
[source,java,indent=0]
5345-
[subs="verbatim,quotes"]
5346-
----
5347-
public class MovieRecommender {
5302+
Using the above configuration ensures Spring initialization failure if any of `${}`
5303+
placeholder could not be resolved. It is also possible to use methods like
5304+
`setPlaceholderPrefix`, `setPlaceholderSuffix` or `setValueSeparator` to customize placeholders.
53485305

5349-
private final String catalog;
5306+
NOTE: Spring Boot configures by default a `PropertySourcesPlaceholderConfigurer` bean that
5307+
will get properties from `application.properties` and `application.yml` files.
53505308

5351-
public MovieRecommender(@Value("#{systemProperties['user.region'] + 'Catalog' }") String catalog){
5352-
this.catalog = catalog;
5353-
}
5354-
----
5309+
Built-in converter support provided by Spring allows simple type conversion (to `Integer`
5310+
or `int` for example) to be automatically handled. Multiple comma separated values parameter
5311+
can be automatically converted to String array without extra effort.
53555312

5356-
SpEL also enables to use more complex data structure:
5313+
It is possible to provide a default value as following:
53575314

53585315
[source,java,indent=0]
53595316
[subs="verbatim,quotes"]
53605317
----
5318+
@Component
5319+
public class MovieRecommender {
53615320
5362-
public class MovieRecommender {
5363-
5364-
private final Map<String, Integer> countOfMoviesPerCatalog;
5321+
private final String catalog;
53655322
5366-
public MovieRecommender(
5367-
@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
5368-
this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
5323+
public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {
5324+
this.catalog = catalog;
5325+
}
53695326
}
5370-
}
5371-
----
5372-
5373-
A widely spread use of `@Value` is placeholder substitution from `@PropertySource`.
5374-
5375-
A default lenient embedded value resolver is provided by Spring. It will try to resolve the property value and if it
5376-
cannot be resolved, the property name will be injected as the value. For instance, according to the following application.properties content:
5377-
5378-
[source,java,indent=0]
5379-
[subs="verbatim,quotes"]
5380-
----
5381-
catalogName=MovieCatalog
53825327
----
53835328

5384-
The following configuration :
5329+
Spring BeanPostProcessor uses ConversionService instance behind the scene to handle the
5330+
process from converting `@Value` value to the target type. If you want to provide conversion
5331+
support for your own custom type, you can provide your own ConversionService bean instance
5332+
as the following example shows:
53855333

53865334
[source,java,indent=0]
53875335
[subs="verbatim,quotes"]
53885336
----
53895337
@Configuration
5390-
@PropertySource("classpath:application.properties")
5391-
public class MyConfig {
5338+
public class AppConfig {
5339+
5340+
@Bean
5341+
public ConversionService conversionService() {
5342+
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
5343+
conversionService.addConverter(new MyCustomConverter());
5344+
return conversionService;
5345+
}
53925346
}
53935347
----
53945348

5395-
And the class:
5349+
<<expressions, `SpEL` expression>> built-in support allows dynamically computed `@Value`
5350+
at runtime as in the following example shows:
53965351

53975352
[source,java,indent=0]
53985353
[subs="verbatim,quotes"]
53995354
----
5355+
@Component
54005356
public class MovieRecommender {
54015357
54025358
private final String catalog;
54035359
5404-
private final String region;
5405-
5406-
public MovieRecommender(
5407-
@Value("${catalogName}") String catalog, @Value("${region}") String region) {
5360+
public MovieRecommender(@Value("#{systemProperties['user.catalog'] + 'Catalog' }") String catalog){
54085361
this.catalog = catalog;
5409-
this.region = region;
54105362
}
54115363
}
54125364
----
54135365

5414-
The `catalog` attribute will be equal to the `"MovieCatalog"` value.
5415-
The region attribute will be equal the `"${region}"` value.
5416-
5417-
If you want to maintain strict control over non existent values, you should declare a `PropertySourcesPlaceholderConfigurer` bean,
5418-
as the following example shows:
5419-
5366+
SpEL also enables to use more complex data structure:
54205367

54215368
[source,java,indent=0]
54225369
[subs="verbatim,quotes"]
54235370
----
5424-
@Configuration
5425-
@PropertySource("classpath:application.properties")
5426-
public class MyConfig {
5371+
@Component
5372+
public class MovieRecommender {
54275373
5428-
@Bean
5429-
public PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
5430-
return new PropertySourcesPlaceholderConfigurer();
5431-
}
5374+
private final Map<String, Integer> countOfMoviesPerCatalog;
5375+
5376+
public MovieRecommender(
5377+
@Value("#{{'Thriller': 100, 'Comedy': 300}}") Map<String, Integer> countOfMoviesPerCatalog) {
5378+
this.countOfMoviesPerCatalog = countOfMoviesPerCatalog;
5379+
}
54325380
}
54335381
----
54345382

5435-
Using the above configuration ensures Spring initialization failure if any of "${}" placeholder could not be resolved.
5436-
5437-
NOTE: Spring Boot configures by default a `PropertySourcesPlaceholderConfigurer` bean that will get properties from `application.properties` and `application.yml` files.
5438-
54395383

54405384
[[beans-postconstruct-and-predestroy-annotations]]
54415385
=== Using `@PostConstruct` and `@PreDestroy`

0 commit comments

Comments
 (0)