[← Relaxed binding](02-relaxed-binding.md) · [Index](../README.md) · [Records and defaults →](04-records-and-defaults.md) # 3. Getting the bean registered `@ConfigurationProperties` on a class does nothing on its own. The class has to become a bean, and there are three ways to arrange that: | How | Where it goes | When to use it | |---|---|---| | `@ConfigurationPropertiesScan` | on the application class | most applications; scans a package | | `@EnableConfigurationProperties(Foo.class)` | on any `@Configuration` class | libraries, or when you want the list explicit | | `@Component` | on the properties class itself | works, but mixes a stereotype into a value type | This project uses `@ConfigurationPropertiesScan`, on [`ConfigBindingApplication`](../src/main/java/com/ankurm/configprops/ConfigBindingApplication.java). ## The failure If none of the three is present, the class compiles, the application starts, and the bean does not exist. Injecting it fails with `NoSuchBeanDefinitionException` — which is at least loud. The quiet version is worse: with constructor binding, a properties *record* that is never registered simply never appears, and if the only thing that used it was optional, nothing complains at all. ## Constructor binding and `@Autowired` do not mix A type bound through its constructor is built by the binder, not by the container. It cannot have collaborators injected into that constructor, because every parameter is treated as a property to bind. If a properties type needs a collaborator, it is not a properties type. ## `@ConfigurationProperties` on an `@Bean` method Legal, and useful when the type comes from a library you cannot annotate: ```java @Bean @ConfigurationProperties(prefix = "demo.thirdparty") ThirdPartyConfig thirdPartyConfig() { return new ThirdPartyConfig(); } ``` This uses setter binding, not constructor binding — the object already exists by the time the binder sees it.