Spring Boot命令行应用main方法调用Service报错求助
问题分析与解决方案
老哥,你的问题根源很明确:你手动new出来的App对象不受Spring容器管理,所以@Autowired标注的MyService根本没被注入,调用myService.save()的时候自然会抛出空指针异常。Spring的依赖注入只对它自己创建并管理的bean生效,你自己new的普通Java对象,Spring才懒得管它的依赖呢😅。
下面给你几种实用的解决办法,按推荐程度排序:
方法一:实现CommandLineRunner接口(最推荐)
Spring Boot专门给命令行应用准备了CommandLineRunner接口,只要你的主类实现它,Spring容器启动完成后会自动调用run方法,这里面可以放心使用注入的服务:
@SpringBootApplication public class App implements CommandLineRunner { @Autowired private MyService myService; public static void main(String[] args) { SpringApplication.run(App.class, args); } @Override public void run(String... args) throws Exception { // 这里直接调用服务就行,当前对象是Spring管理的bean,依赖已经注入好了 myService.save(); } }
方法二:从ApplicationContext获取Bean
如果你就想在main方法里直接操作,可以通过SpringApplication.run的返回值拿到ApplicationContext,再从中取出MyService的实例:
@SpringBootApplication public class App { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(App.class, args); MyService myService = context.getBean(MyService.class); myService.save(); } }
这种方式不用把App本身变成bean,直接从容器里拿需要的服务就行,适合简单的命令行场景。
方法三:使用@PostConstruct注解(不推荐用于命令行启动)
如果你的需求不是一次性执行命令,而是bean初始化后要做的操作,可以用@PostConstruct,但它会在bean创建时执行,不太适合命令行启动的一次性任务:
@SpringBootApplication public class App { @Autowired private MyService myService; public static void main(String[] args) { SpringApplication.run(App.class, args); } @PostConstruct public void init() { myService.save(); } }
再给你划个重点
new App()创建的是普通Java对象,Spring完全不知道它的存在,不会帮它注入任何依赖- 只有Spring通过@Component、@Service、@SpringBootApplication等注解创建并管理的bean,才能享受依赖注入的功能
内容的提问来源于stack exchange,提问作者Roland
相关产品推荐
相关产品推荐

