自动装配 class 方法的空指针异常

Null pointer exception for autowired class method

我是 Apache Camel 的新手,正在尝试构建 api。它有三个 classes.

Class A - 这是为了读取 application.properties 文件,如下所示

@Configuration
@ConfigurationProperties(prefix="api")
public class A{

private String username;

public String getUsername(){
    return username
}

Class B - Apache 骆驼路线。

Class C - Bean class 其中 class A 是自动装配的。

@Component
public class b extends RouteBuilder{
    @Autowired
    ClassC customC;

    public void configure{
        from("direct:start")
            .bean(customC)
            .to("log:first-timer")
    }
}

@Component
class C{
    @Autowired
    ClassA config;

    String username=config.getUsername();
}

每当 IDE 执行 api 时,它会在行 String username=config.getUsername(); 中抛出空指针异常。我已经验证 spring 引导能够加载 application.properties.

我不确定为什么调用自动装配的方法 class 会抛出空指针异常。

问题出在你的 C class.

@Component
class C{
    @Autowired
    A config;

    String username = config.gtUsername();
}

Spring初始化的顺序是这样的:

  1. 创建 C
    的实例 (通过调用 new C()
    此构造函数调用 username = config.gtUsername() 并以 NullPointerException 失败,因为 config 仍然是 null.
  2. 处理 @Autowired
    (初始化你的config属性)
    但是当然它并没有走到这一步,因为异常已经在步骤 1 中发生了。

您可以通过删除 username 的初始化来解决此问题 属性 来自构造函数,而是将其放入单独的方法中 (我们称它为 init())并用 @PostConstruct 注释它。 另见 Spring PostConstruct and PreDestroy Annotations.

@Component
class C{
    @Autowired
    A config;

    String username;
    
    @PostConstruct
    void init() {
        username = config.getUsername();
    }
}

那么Spring初始化的顺序是这样的:

  1. 创建一个 C 实例
    (通过调用 new C()
  2. 处理 @Autowired.
    (这会初始化你的 config 属性)
  3. 调用 @PostConstruct-注释方法。
    (这会使用已经初始化的 config 属性 初始化您的 username 属性)

解决问题的另一种更简单的方法是使用构造函数 注入(正如@Ferry 已经在他的评论中建议的那样):

不再依赖隐式默认构造函数, 你提供了一个 @Autowired 注释的构造函数,它 可以采用 A config 参数。 此外:这样做,您将不需要 A config 属性 了。

@Component
class C{ 
    String username;

    @Autowired
    C(A config) {
        username = config.getUsername();
    }
}

那么Spring初始化的顺序是这样的:

  1. 处理 @Autowired
    (通过调用 new C(config) 创建 C 的实例,其中 config 是先前在自动装配过程中创建的 A 实例)
    这使用构造函数接收的 config 初始化您的 username 属性。