anchor.diff:  [[boot-features-external-config-typesafe-configuration-properties]]
   === Type-safe Configuration Properties
   Using the `@Value("${property}")` annotation to inject configuration properties can
  -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 allows strongly typed beans to govern and validate
  -the configuration of your application. For example:
  -
  -[source,java,indent=0]
  -----
  -	@ConfigurationProperties(prefix="connection")
  -	public class ConnectionProperties {
  -
  -		private String username;
  +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 allows strongly typed beans to govern and validate the configuration of
  +your application.
  +
  +[source,java,indent=0]
  +----
  +	package com.example;
  +
  +	import java.net.InetAddress;
  +	import java.util.ArrayList;
  +	import java.util.Collections;
  +	import java.util.List;
  +
  +	import org.springframework.boot.context.properties.ConfigurationProperties;
  +
  +	@ConfigurationProperties("foo")
  +	public class FooProperties {
  +
  +		private boolean enabled;
   
   		private InetAddress remoteAddress;
   
  -		// ... getters and setters
  -
  -	}
  -----
  -
  -NOTE: The getters and setters are advisable, since binding is via standard Java Beans
  -property descriptors, just like in Spring MVC. They are mandatory for immutable types or
  -those that are directly coercible from `String`. As long as they are initialized, maps,
  -collections, and arrays need a getter but not necessarily a setter since they can be
  -mutated by the binder. If there is a setter, Maps, collections, and arrays can be created.
  -Maps and collections can be expanded with only a getter, whereas arrays require a setter.
  -Nested POJO properties can also be created (so a setter is not mandatory) if they have a
  -default constructor, or a constructor accepting a single value that can be coerced from
  -String. Some people use Project Lombok to add getters and setters automatically.
  +		private final Security security = new Security();
  +
  +		public boolean isEnabled() { ... }
  +
  +		public void setEnabled(boolean enabled) { ... }
  +
  +		public InetAddress getRemoteAddress() { ... }
  +
  +		public void setRemoteAddress(InetAddress remoteAddress) { ... }
  +
  +		public Security getSecurity() { ... }
  +
  +		public static class Security {
  +
  +			private String username;
  +
  +			private String password;
  +
  +			private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
  +
  +			public String getUsername() { ... }
  +
  +			public void setUsername(String username) { ... }
  +
  +			public String getPassword() { ... }
  +
  +			public void setPassword(String password) { ... }
  +
  +			public List<String> getRoles() { ... }
  +
  +			public void setRoles(List<String> roles) { ... }
  +
  +		}
  +	}
  +----
  +
  +The POJO above defines the following properties:
  +
  +* `foo.enabled`, `false` by default
  +* `foo.remote-address`, with a type that can be coerced from `String`
  +* `foo.security.username`, with a nested "security" whose name is determined by the name
  +of the property. In particular the return type is not used at all there and could have
  +been `SecurityProperties`
  +* `foo.security.password`
  +* `foo.security.roles`, with a collection of `String`
  +
  +[NOTE]
  +====
  +Getters and setters are usually mandatory, since binding is via standard Java Beans
  +property descriptors, just like in Spring MVC. There are cases where a setter may be
  +omitted:
  +
  +* Maps, as long as they are initialized, need a getter but not necessarily a setter since
  +they can be mutated by the binder.
  +* Collections and arrays can be either accessed via an index (typically with YAML) or
  +using a single comma-separated value (properties). In the latter case, a setter is
  +mandatory. We recommend to always add a setter for such types. If you initialize a
  +collection, make sure it is not immutable (as in the example above)
  + * If nested POJO properties are initialized (like the `Security` field in the example
  +above), a setter is not required. If you want the binder to create the instance on-the-fly
  +using its default constructor, you will need a setter.
  +
  +Some people use Project Lombok to add getters and setters automatically. Make sure that
  +Lombok doesn't generate any particular constructor for such type as it will be used
  +automatically by the container to instantiate the object.
  +====
   
   TIP: See also the <<boot-features-external-config-vs-value,differences between `@Value`
   and `@ConfigurationProperties`>>.
  
positive.code: 
  [source,java,indent=0]
  ----
  	@ConfigurationProperties(prefix = "foo")
  	@Bean
  	public FooComponent fooComponent() {
  		...
  	}
  ----
  
  Any property defined with the `foo` prefix will be mapped onto that `FooComponent` bean
  in a similar manner as the `ConnectionProperties` example above.
  
  
  
  
negative.code: 
  In order to validate values of nested properties, you must annotate the associated field
  as `@Valid` to trigger its validation. For example, building upon the above
  `FooProperties` example:
  
  [source,java,indent=0]
  ----
  	@ConfigurationProperties(prefix="connection")
  	public class FooProperties {
  
  		@NotNull
  		private InetAddress remoteAddress;
  
  		@Valid
  		private final Security security = new Security();
  
  		// ... getters and setters
  
  		public static class Security {
  
  			@NotEmpty
  			public String username;
  
  			// ... getters and setters
  
  