一. 问题背景

很多小伙伴都知道SpringBoot中常见的配置文件有三种,分别是yml、yaml、properties三种类型。

而有些时候我们需要在SpringBoot配置文件中去配置一些自定义的内容,比如邮箱的秘钥信息以及短信秘钥信息等。而配置完毕之后我们就需要进行配置的读取,在SpringBoot常见读取自定义配置信息的方式有两种,分别为@Value以及@ConfigurationProperties。

另外我们要注意,使用@ConfigurationProperties的时候,需要在pom文件中引入

spring-boot-configuration-processor的起步依赖。但是在读取配置数据的过程中,如果不注意细节的话,就会容易引发让人迷惑的空指针异常!!!

二. 实际案例
先给大家设计一个案例,实现过程如下:
2.1 创建学生简介类

public class StudentIntroduce {
    private int id;
    private String detailed;
    public StudentIntroduce() {
    }
    public StudentIntroduce(int id, String detailed) {
        this.id = id;
        this.detailed = detailed;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getDetailed() {
        return detailed;
    }
    public void setDetailed(String detailed) {
        this.detailed = detailed;
    }
    @Override
    public String toString() {
        return "StudentIntroduce{" +
                "id=" + id +
                ", detailed='" + detailed + '\'' +
                '}';
    }
}

2.2 准备一个学生类同时关联学生简介类

public class Student {
    private String name;
    private String sex;
    private StudentIntroduce studentIntroduce;
    public Student() {
    }
    public Student(String name, String sex, StudentIntroduce studentIntroduce) {
        this.name = name;
        this.sex = sex;
        this.studentIntroduce = studentIntroduce;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public StudentIntroduce getStudentIntroduce() {
        return studentIntroduce;
    }
   public void setStudentIntroduce(StudentIntroduce studentIntroduce) {
        this.studentIntroduce = studentIntroduce;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", studentIntroduce=" + studentIntroduce +
                '}';
    }
}

2.3 在yml文件中配置学生类需要的数据

yaml文件内容如下:

student:
  name: zhangsan
  sex: male
  introduce:
    id: 1
    detailed: The student is very excellent !!!

2.4 读取yml文件的数据

我们选择@ConfigurationProperties方式读取,此时在学生类上方加上注解并指定yml中的前缀。

springboot的空构造函数_spring


Tips:一定要在学生类以及学生简介类中国提供getter和setter方法,不然读取数据注入将会失败,因为@ConfigurationProperties注入数据的原理,是根据set方法实现的。

2.5 准备配置类将学生对象注入进IOC容器

@Configuration
public class StudentConfig {
    @Bean
    public Student getStudentDetail(){
        return new Student();
    }
}

2.6 在启动类中获取容器并得到学生类的bean对象

@SpringBootApplication
public class GateWayService9527 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(GateWayService9527.class);
        Student student = (Student) context.getBean("getStudentDetail");
        StudentIntroduce studentIntroduce = student.getStudentIntroduce();
        System.out.println(studentIntroduce.getDetailed());
    }
}

2.7 运行启动类会发现控制台出现空指针异常

springboot的空构造函数_自定义_02


2.8 原因解析

springboot的空构造函数_自定义_03


2.9 解决办法以及建议

在yaml文件中做自定义配置时,需要将配置的key名与注入类名的变量名一致!!!

student:
  name: zhangsan
  sex: male
  studentIntroduce:  ##修改位置
    id: 1
    detailed: The student is very excellent !!!

重新运行启动类!!!

springboot的空构造函数_spring boot_04

三. 总结

本文出现的问题只是在开发中比较常见的一些问题,但对于我们开发人员来讲,我们在完成业务开发的同时,也应该追求细致以及善于预判和分析,这样才能让我们在互联网这个领域不断积累丰富的经验!!!