spring的构造函数注入属性@ConstructorBinding

spring的构造函数注入属性@ConstructorBinding,第1张

文章目录
  • 0. 前言
  • 1. 先说结论
  • 2. 快速入门
  • 3. 其他情况案例
    • 1. 属性不在构造函数的参数列表中,无法被注入
    • 2. 使用@ConstructorBinding的类上再使用@Component注解,会报错

0. 前言
  1. 前情回顾:
    实体类使用@Builder,导致@ConfigurationProperties注入属性失败
  2. 根据上一篇文章,引出如下问题:
1. 先说结论
  1. @ConstructorBinding注解:这个注解是SpringBoot在2.2发行版中添加的,添加该注解的属性配置类不再需要添加Setter方法,但是需要添加构造函数,根据构造函数进行实例化属性配置类。
  2. 使用@ConstructorBinding,该类得拥有 有参的构造函数方法,才可以赋值成功。
  3. @ConstructorBinding注解的类,此类不能加@Component类似声明该类为bean对象的注解,因为spring创建bean的时候,有种方式叫构造函数创建bean,如果此类加上@Component,构造函数的参数,则都是去单例池中找对象并注入。
  4. 回答上一篇问题:
    1. 使用该@ConstructorBinding注解,进行构造函数方法注入属性,可以不用set方法,因此完全可以不用提供set方法。
    2. 如果不想提供无参的构造函数方法,使用@Builder,因为@Builder可以把无参构造函数给抹杀掉,拥有全参构造函数,再配合@ConstructorBinding即可,属性注入。
2. 快速入门
// @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);
    }
}

运行结果图:

3. 其他情况案例 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类型的单例对象,所以报错了。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/735830.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-27
下一篇 2022-04-27

发表评论

登录后才能评论

评论列表(0条)

保存