Spring @自动连线符号未按预期工作

Spring @自动连线符号未按预期工作,spring,spring-boot,autowired,Spring,Spring Boot,Autowired,每当我访问bi的属性时,就会得到一个NullPointerException。我知道@Autowired符号不起作用。但是为什么呢 注意:两个类都在同一个包下 附加问题:因为我想在spring应用程序启动时运行一个方法。这是最好的方法吗?因为@pepevalbe的答案已经为我提供了所需的解决方法。在spring应用程序启动时,还有其他方法可以运行方法吗?因为您不能@autowire静态类。它没有被初始化,所以你在尝试使用它时会得到一个NPE 将bean连接到静态类中有一些变通方法,但强烈建议不要

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

注意:两个类都在同一个包下


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

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

将bean连接到静态类中有一些变通方法,但强烈建议不要这样做

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

@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 {
    ...
}

有几个原因@Autowired可能无法工作

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

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

在main方法中,您可以引用上下文并从中访问bean书目索引。在静态中,主spring不能创建和注入bean,所以这就是如何从上下文中获取它的方法

公共静态无效字符串[]args{ ApplicationContext上下文=SpringApplication.runMainApplication.class,args; 书目索引器书目索引器=context.getBeanBibliographyIndex.class; 书目索引:reindex.reindex; }
您也可以按中的操作,并在初始化后执行此代码。

您的问题是无法在main中使用bi,因为main是静态的。 使双静态没有帮助,因为静态字段不会被@Autowired,这是可能的,但在依赖注入的概念中没有意义


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

从书目索引中删除static,但我将无法在main函数下访问它。您不能注入静态字段。你也不应该在你的主页上那样访问它。run方法返回一个ApplicationContext,您可以使用它使用getBean获取书目索引。或者创建一个@Bean方法,该方法返回一个CommandLineRunner,您给它一个书目索引并在那里调用该方法。如果是这种情况,那么我如何能够在主函数下使用任何自动连接的变量而不将其声明为静态?您不应该在主函数下编写代码。如果需要在初始化后执行代码,可以添加事件侦听器。我将扩展我的答案,在main函数下,我实例化了一个使用autowired类的对象。但是,当我使用该对象并访问autowired类时,它仍然为null。这是在spring应用程序启动时运行方法的最佳方法吗?有许多替代方法,您可以编写一个实现CommandLineRunner或ApplicationRunner接口的组件类。这里有一些例子:这是必要的吗?我看到的例子并没有明确地做到这一点。在静态中,主spring不能创建和注入bean,所以这就是如何从上下文中获取它@奥利瓦克勒
@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();
    }
}