@Autowired 表示法未按预期工作

@Autowired notation is not working as expected

@SpringBootApplication
public class MainApplication {

    @Autowired
    static BibliographyIndexer bi;

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

}


@Repository
public class BibliographyIndexer {
    ...
}

每当我访问 bi 的属性时,我都会得到一个 NullPointerException。我知道 @Autowired 符号不起作用。但是为什么?

注:两个类在同一个包下

附加问题:因为我想在 spring 应用程序启动时 运行 一个方法。这是最好的方法吗,因为@pepevalbe 的回答已经为我提供了所需的解决方法。在 spring 应用程序启动时是否有另一种方法 运行 方法?

因为你不能@Autorwire 静态 class。它没有被初始化,所以你在尝试使用它时会得到一个 NPE。

有一些解决方法可以将 bean 连接到静态 class,但强烈建议不要这样做。

编辑: 如果你需要在初始化后执行代码,你可以添加一个事件监听器:

@SpringBootApplication
public class MainApplication {

    @Autowired  
    BibliographyIndexer bi;

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

    @EventListener(ApplicationReadyEvent.class)
    public void doAfterStartUp() {
        bi.reindex();
    }
}

@Autowired 可能无法工作的原因有多种。

当新实例不是由 Spring 创建,而是通过例如手动调用构造函数创建时,class 的实例将不会在 Spring 上下文中注册,因此不可用于依赖注入。此外,当您在创建新实例的 class 中使用 @Autowired 时,它不会知道 Spring 上下文,因此这很可能也会失败。 另一个原因可能是您要在其中使用 @Autowired 的 class 未被 ComponentScan 拾取。这基本上可以是因为两个原因。

包在 ComponentScan 搜索路径之外。将包移动到扫描位置或配置 ComponentScan 来修复此问题。 您要在其中使用@Autowired 的 class 没有 Spring 注释。将以下注释之一添加到 class:@Component、@Repository、@Service、@Controller、@Configuration。他们有不同的行为,所以谨慎选择......

main 方法中,您可以引用 context 并从中访问 bean BibliographyIndexer。在 static main spring 中无法创建和注入 bean,因此这就是您从 context 中获取它的方法。

public static void main(String[] args) {
  ApplicationContext  context = SpringApplication.run(MainApplication.class, args);
  BibliographyIndexer bibliographyIndexer = context.getBean(BibliographyIndexer.class);
  bibliographyIndexer.reindex();
}

你也可以像一样,在初始化后执行这段代码。

您的问题是您不能在 main 中使用 bi,因为 main 是静态的。 使 bi 静态无济于事,因为静态字段不会 @Autowired(这是可能的,但在依赖注入的概念中没有意义)。

删除 static 并将 bi.reindex() 移动到使用 @PostConstruct 注释的新方法。它将在 MainApplication-bean 完全初始化后执行,在这里您可以使用注入的 bi.