使用字段[重复]时,Spring Boot Autowired 在 Main() 中抛出 NullPointerException

问题描述 投票:0回答:1

注意:自从我找到解决方案后,我正在更新此内容。

这个问题类似于Why is my Spring @Autowired field null?,但我在这里使用

main()
方法。解决方案是用
Foo
标记
@Component
并通过
Main
方法将其自动装配到
@PostConstruct
中。我通过如何使用 main(String[] args) 方法中的自动装配(@Autowired)引用了解了这一点?

关于PostContruct:为什么使用@PostConstruct?

@PostConstruct
确保所有 bean 在执行之前已完全初始化(包括您正在编辑的 bean 类)。

但更大的问题是我在做

Foo foo = new Foo()
foo
超出了 Spring 上下文的范围,它 100% 的生命周期由我管理。通过自动装配所有内容,将所有内容放回 Spring 手中:

新的Main.java

package org.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.PostConstruct;

@SpringBootApplication
public class Main {
    @Autowired
    Foo foo;

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @PostConstruct
    public void test() {
        foo.message();
    }
}

新Foo.java

package org.example;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
@Slf4j
public class Foo {

    @Autowired
    Bar bar;

    public Foo() {
        log.info("Foo bean created");
    }

    public void message() {
        log.info(bar.getWord());
    }

}

原问题如下:

我已经遵循了很多这样的 Spring 教程,但它对我来说从来不起作用。不知道我做错了什么,但我真的需要帮助来解决这个问题。

Main.java

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);

        Foo foo = new Foo();
        foo.message();
    }
}

Foo.java

package org.example;

import org.springframework.beans.factory.annotation.Autowired;

public class Foo {

    @Autowired
    Bar bar;

    public void message() {
        System.out.println(bar.getWord());
    }

}

Bar.java

package org.example;

import org.springframework.stereotype.Component;

@Component
public class Bar {
    String word = "word";

    public String getWord() {return word;}
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>untitled</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.7.5</version>
        </dependency>

    </dependencies>

</project>

从 Main() 运行时,我得到:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "org.example.Bar.getWord()" because "this.bar" is null
    at org.example.Foo.message(Foo.java:11)
    at org.example.Main.main(Main.java:14)

这些都在同一个目录/包中。我已经研究了两个小时,但不知道为什么这不起作用。对此的任何帮助将不胜感激。

我尝试过的:

  • 使用 @Autowired 创建一个可以在另一个类中使用的 bean。

我预期会发生什么:

  • 要打印到控制台的字符串
    word
  • 我的理解是,如果您使用 @Autowired 来注入一个具有 @Component 的类,那么 Spring 会将其作为一个 bean。我已经满足了该标准,但没有得到预期的结果。

实际结果:

  • 空指针异常
java spring spring-boot autowired
1个回答
1
投票

Autowired 仅在注入组件时才起作用。您还必须使 Foo 成为一个组件(或定义一个 bean),并将其自动装配到您的主类中才能正常工作。或者,您可以使用 ApplicationContext 的实例。

您也不需要

@ComponentScan
注释,因为
@SpringBootApplication
已经有了它。

参见:https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/using-boot-using-springbootapplication-annotation.html

© www.soinside.com 2019 - 2024. All rights reserved.