spring的构造函数注入属性@ConstructorBinding用法
作者:搏·梦
这篇文章主要介绍了关于spring的构造函数注入属性@ConstructorBinding用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
前言
前情回顾:
实体类使用@Builder,导致@ConfigurationProperties注入属性失败
根据上一篇文章,引出如下问题:
先说结论
@ConstructorBinding注解:这个注解是SpringBoot在2.2发行版中添加的,添加该注解的属性配置类不再需要添加Setter方法,但是需要添加构造函数,根据构造函数进行实例化属性配置类。
使用@ConstructorBinding,该类得拥有 有参的构造函数方法,才可以赋值成功。
@ConstructorBinding注解的类,此类不能加@Component类似声明该类为bean对象的注解,因为spring创建bean的时候,有种方式叫构造函数创建bean,如果此类加上@Component,构造函数的参数,则都是去单例池中找对象并注入。
回答上一篇问题:
- 使用该@ConstructorBinding注解,进行构造函数方法注入属性,可以不用set方法,因此完全可以不用提供set方法。
- 如果不想提供无参的构造函数方法,使用@Builder,因为@Builder可以把无参构造函数给抹杀掉,拥有全参构造函数,再配合@ConstructorBinding即可,属性注入。
快速入门
// @EnableConfigurationProperties的具体使用方式可以看如下: // https://blog.csdn.net/xueyijin/article/details/124072389 @Component @EnableConfigurationProperties(demoFailedTest.class) @ToString public class demoFailedConfig { @Autowired private demoFailedTest demoFailedTest; } @ToString @ConfigurationProperties(prefix = "failed.test") @ConstructorBinding @AllArgsConstructor public class demoFailedTest { private String username; private int age; private demoPerson demoPerson; } @ToString @AllArgsConstructor @ConstructorBinding public class demoPerson { private String name; private String sex; } @Component("demoFailedTestRunner") public class demoRunner implements ApplicationRunner { @Autowired demoFailedConfig demoFailedConfig; @Override public void run(ApplicationArguments args) throws Exception { System.out.println(demoFailedConfig); } }
运行结果图:
其他情况案例
1.属性不在构造函数的参数列表中
无法被注入
@Component @EnableConfigurationProperties(demoFailedTest.class) @ToString public class demoFailedConfig { @Autowired private demoFailedTest demoFailedTest; } @ToString @ConfigurationProperties(prefix = "failed.test") @ConstructorBinding public class demoFailedTest { private String username; private int age; private demoPerson demoPerson; // 少了age属性 public demoFailedTest(String username, com.example.csdn.configuration_failed_test.demoPerson demoPerson) { this.username = username; this.demoPerson = demoPerson; } } @ToString @ConstructorBinding public class demoPerson { private String name; private String sex; // 少了name属性 public demoPerson(String sex) { this.sex = sex; } } @Component("demoFailedTestRunner") public class demoRunner implements ApplicationRunner { @Autowired demoFailedConfig demoFailedConfig; @Override public void run(ApplicationArguments args) throws Exception { System.out.println(demoFailedConfig); } }
2.使用@ConstructorBinding的类上再使用@Component注解
会报错
@Component @EnableConfigurationProperties(demoFailedTest.class) @ToString public class demoFailedConfig { @Autowired private demoFailedTest demoFailedTest; } @Component @ToString @ConfigurationProperties(prefix = "failed.test") @ConstructorBinding @Builder public class demoFailedTest { private String username; private int age; private demoPerson demoPerson; } @ToString @ConstructorBinding @Builder public class demoPerson { private String name; private String sex; } @Component("demoFailedTestRunner") public class demoRunner implements ApplicationRunner { @Autowired demoFailedConfig demoFailedConfig; @Override public void run(ApplicationArguments args) throws Exception { System.out.println(demoFailedConfig); } }
可以从报错信息看出来,spring将该demoFailedTest类执行构造函数方法的时候,当成创建该类的单例bean对象,因此,该构造函数所需的参数,必然是从单例池中去找,显示是没有String类型的单例对象,所以报错了。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。