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