anchor.diff:  	  profiles: dev
   	acme:
   	  list:
  -        - name: my another name
  +	    - name: my another name
   ----
   
   If the `dev` profile is not active, `AcmeProperties.list` contains one `MyPojo` entry,
  
positive.code: This configuration _does not_ add a second `MyPojo` instance to the list, and it does not
  merge the items.
  
  When a collection is specified in multiple profiles, the one with the highest priority
  (and only that one) is used. Consider the following example:
  
  [source,yaml,indent=0]
  ----
  	acme:
  	  list:
  		- name: my name
  		  description: my description
  		- name: another name
  		  description: another description
  	---
  	spring:
  	  profiles: dev
  	acme:
  	  list:
  		 - name: my another name
  ----
  
  In the preceding example, if the `dev` profile is active, `AcmeProperties.list` contains
  _one_ `MyPojo` entry (with a name of `my another name` and a description of `null`).
  
  
  
  [[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 lets strongly typed beans govern and validate the configuration of
  your application, as shown in the following example:
  
  [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("acme")
  	public class AcmeProperties {
  
  		private boolean enabled;
  
  		private InetAddress remoteAddress;
  
  		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 preceding POJO defines the following properties:
  
  * `acme.enabled`, with a value of `false` by default.
  * `acme.remote-address`, with a type that can be coerced from `String`.
  * `acme.security.username`, with a nested "security" object 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`.
  * `acme.security.password`.
  * `acme.security.roles`, with a collection of `String`.
  
  [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:
  
  * 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 accessed either through an index (typically with YAML) or
  by 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 preceding example).
  * If nested POJO properties are initialized (like the `Security` field in the preceding
  example), a setter is not required. If you want the binder to create the instance on the
  fly by using its default constructor, you need a setter.
  
  Some people use Project Lombok to add getters and setters automatically. Make sure that
  Lombok does not generate any particular constructor for such a type, as it is used
  automatically by the container to instantiate the object.
  
  Finally, only standard Java Bean properties are considered and binding on static
  properties are 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:
  
  [source,java,indent=0]
  ----
  	@Configuration
  	@EnableConfigurationProperties(AcmeProperties.class)
  	public class MyConfiguration {
  	}
  ----
  
  [NOTE]
  ====
  When the `@ConfigurationProperties` bean is registered that way, the bean has a
  conventional name: `<prefix>-<fqn>`, where `<prefix>` is the environment key prefix
  specified in the `@ConfigurationProperties` annotation and `<fqn>` is the fully qualified
  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`.
  ====
  
  Even if 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. Having said that, the
  `@EnableConfigurationProperties` annotation is _also_ automatically applied to your
  project so that any _existing_ bean annotated with `@ConfigurationProperties` is
  configured from the `Environment`. You could shortcut `MyConfiguration` by making sure
  `AcmeProperties` is already a bean, as shown in the following example:
  
  [source,java,indent=0]
  ----
  	@Component
  	@ConfigurationProperties(prefix="acme")
  	public class AcmeProperties {
  
  		// ... see the preceding example
  
  	}
  ----
  
  This style of configuration works particularly well with the `SpringApplication` external
  YAML configuration, as shown in the following example:
  
  [source,yaml,indent=0]
  ----
  	# application.yml
  
  	acme:
  		remote-address: 192.168.1.1
  		security:
  			username: admin
  			roles:
  			  - USER
  			  - ADMIN
  
  	# additional configuration as required
  ----
  
  To work with `@ConfigurationProperties` beans, you can inject them in the same way
  as any other bean, as shown in the following example:
  
  [source,java,indent=0]
  ----
  	@Service
  	public class MyService {
  
  		private final AcmeProperties properties;
  
  		@Autowired
  		public MyService(AcmeProperties properties) {
  		    this.properties = properties;
  		}
  
  	 	//...
  
  		@PostConstruct
  		public void openConnection() {
  			Server server = new Server(this.properties.getRemoteAddress());
  			// ...
  		}
  
  	}
  ----
  
  TIP: Using `@ConfigurationProperties` also lets you generate metadata files that can be
  used by IDEs to offer auto-completion for your own keys. See the
  <<configuration-metadata>> appendix for details.
  
  
  
  [[boot-features-external-config-3rd-party-configuration]]
  ==== Third-party Configuration
  As well as using `@ConfigurationProperties` to annotate a class, you can also use it on
  public `@Bean` methods. Doing so can be particularly useful when you want to bind
  properties to third-party components that are outside of your control.
  
  To configure a bean from the `Environment` properties, add `@ConfigurationProperties` to
  its bean registration, as shown in the following example:
  
  [source,java,indent=0]
  ----
  	@ConfigurationProperties(prefix = "another")
  	@Bean
  	public AnotherComponent anotherComponent() {
  		...
  	}
  ----
  
  Any property defined with the `another` prefix is mapped onto that `AnotherComponent` bean
  in manner similar to the preceding `AcmeProperties` example.
  
  
  
  [[boot-features-external-config-relaxed-binding]]
  ==== Relaxed Binding
  Spring Boot uses some relaxed rules for binding `Environment` properties to
  `@ConfigurationProperties` beans, so there does not need to be an exact match between the
  `Environment` property name and the bean property name.  Common examples where this is
  useful include dash-separated environment properties (for example, `context-path` binds
  to `contextPath`), and capitalized environment properties (for example, `PORT` binds to
  `port`).
  
  For example, consider the following `@ConfigurationProperties` class:
  
  [source,java,indent=0]
  ----
  	@ConfigurationProperties(prefix="acme.my-project.person")
  	public class OwnerProperties {
  
  		private String firstName;
  
  		public String getFirstName() {
  			return this.firstName;
  		}
  
  		public void setFirstName(String firstName) {
  			this.firstName = firstName;
  		}
  
  	}
  ----
  
  In the preceding example, the following properties names can all be used:
  
  .relaxed binding
  [cols="1,4"]
  |===
  | Property | Note
  
  |`acme.my-project.person.first-name`
  |Kebab case, which is recommended for use in `.properties` and `.yml` files.
  
  |`acme.myProject.person.firstName`
  |Standard camel case syntax.
  
  |`acme.my_project.person.first_name`
  |Underscore notation, which is an alternative format for use in `.properties` and `.yml`
  files.
  
  |`ACME_MYPROJECT_PERSON_FIRSTNAME`
  |Upper case format, which is recommended when using system environment variables.
  |===
  
  NOTE: The `prefix` value for the annotation _must_ be in kebab case (lowercase and
  separated by `-`, such as `acme.my-project.person`).
  
  .relaxed binding rules per property source
  [cols="2,4,4"]
  |===
  | Property Source | Simple | List
  
  |Properties Files
  |Camel case, kebab case, or underscore notation
  |Standard list syntax using `[ ]` or comma-separated values
  
  |YAML Files
  |Camel case, kebab case, or underscore notation
  |Standard YAML list syntax or comma-separated values
  
  |Environment Variables
  |Upper case format with underscore as the delimiter. `_` should not be used within a
  property name
  |Numeric values surrounded by underscores, such as `MY_ACME_1_OTHER = my.acme[1].other`
  
  |System properties
  |Camel case, kebab case, or underscore notation
  |Standard list syntax using `[ ]` or comma-separated values
  |===
  
  TIP: We recommend that, when possible, properties are stored in lower-case kebab format,
  such as `my.property-name=acme`.
  
  
  [[boot-features-external-config-conversion]]
  ==== Properties Conversion
  
negative.code: 		}
  	}
  ----
  
  
  
  