结论: 这个注解主要是为了将配置文件中的属性映射到实体类上,并且支持嵌套映射。
代码说明:
@ConfigurationProperties(prefix = "person") @Data public class Person { String name; Integer age; //Dog dog; }
@SpringBootApplication @EnableConfigurationProperties({Person.class}) public class CustomApplication implements ApplicationRunner,ApplicationContextAware { ApplicationContext applicationContext; public static void main(String[] args) { SpringApplication.run(CustomApplication.class, args); } /* *这个地方也可以直接注入Person * @autowired * private Person person; * */ @Override public void run(ApplicationArguments args) throws Exception { Person bean = applicationContext.getBean(Person.class); System.out.println(bean); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
# 这是我的application.yml文件 person: name: zhangsan age: 12
启动chen程序后控制台打印:Person(name=zhangsan, age=12)
证明:配置中的值被映射到了实体类中。
嵌套映射:
新增实体类:
@Data public class Dog { private String name; }
同时将personle类中的注解打开,我这里就不贴重复的代码了,yml文件中新增如下
person: name: zhangsan age: 12 dog: name: wangwang
运行程序结果如下:
Person(name=zhangsan, age=12, dog=Dog(name=wangwang))
证明嵌套映射没有问题。
之前一直不明白为什么@ConfigurationProperties跟@EnableConfigurationProperties需要同时使用。跟踪@EnableConfigurationProperties源码发现如下代码:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented // 导入了EnableConfigurationPropertiesImportSelector,我们继续跟踪这个类 @Import({EnableConfigurationPropertiesImportSelector.class}) public @interface EnableConfigurationProperties { Class<?>[] value() default {}; }
public static class ConfigurationPropertiesBeanRegistrar implements ImportBeanDefinitionRegistrar { public ConfigurationPropertiesBeanRegistrar() { } public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { this.getTypes(metadata).forEach((type) -> { this.register(registry, (ConfigurableListableBeanFactory)registry, type); }); } ........
其实就是将我们在@EnableConfigurationProperties({Person.class})定义的class注册到spring容器中,对于我们的案例来说,就是将person类注册到容器中。为了验证我的想法,我将@EnableConfigurationProperties注解注释,并给person类型添加了@component注解
代码如下:
@ConfigurationProperties(prefix = "person") @Data @Component // 新增注解 public class Person { String name; Integer age; Dog dog; } @SpringBootApplication //@EnableConfigurationProperties({Person.class}) 去除这个注解 public class CustomApplication implements ApplicationRunner,ApplicationContextAware { ApplicationContext applicationContext; public static void main(String[] args) { SpringApplication.run(CustomApplication.class, args); } @Autowired Person person; @Override public void run(ApplicationArguments args) throws Exception { Person bean = applicationContext.getBean(Person.class); System.out.println(person); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
程序照样正常运行,验证正确~
//