@Autowired表示法无法按预期工作

时间:2019-11-12 08:43:19

标签: spring spring-boot autowired

@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应用程序启动时,还有另一种方法可以运行方法吗?

4 个答案:

答案 0 :(得分:1)

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

有一些变通方法可以将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();
    }
}

答案 1 :(得分:0)

@Autowired可能不起作用的原因有很多。

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

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

答案 2 :(得分:0)

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();
}

您还可以像在answer from pepevalbe中一样在初始化后执行此代码。

答案 3 :(得分:0)

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

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