You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:34:10