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

Spring Boot求助:@SpringBootApplication无法自动注入Service且抛空指针

解决Spring Boot中@Autowired静态字段为Null的问题

嘿,我一眼就看穿问题所在了——你遇到的NullPointerException根本和scanBasePackages配置无关,核心原因是Spring不支持给静态字段做@Autowired注入!

为什么会这样?

Spring的依赖注入是基于对象实例的,它管理的是一个个Bean实例;而静态字段属于类本身,不属于任何对象实例,所以Spring容器没办法把Bean注入到静态变量里。你看到ThreadPoolTaskExecutor能正常初始化,是因为它是通过@Bean声明的独立Bean,Spring直接管理这个实例,和静态注入完全没关系——你的MyCustomService其实已经被Spring扫描到并创建了,只是静态变量拿不到它而已。

具体解决方案

这里给你两种靠谱的解决办法,按需选择:

方案1:改用非静态字段(推荐)

把静态的myCustomService改成实例字段,然后通过Spring上下文获取App实例来调用方法,或者用@PostConstruct在初始化完成后执行逻辑:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class App{
    private static Logger logger = LoggerFactory.getLogger(App.class);

    @Autowired
    private MyCustomService myCustomService; // 去掉static修饰符

    public static void main(String[] args) {
        // 获取Spring上下文
        ApplicationContext context = SpringApplication.run(App.class, args);
        // 获取App类的实例
        App appInstance = context.getBean(App.class);
        // 通过实例调用方法
        appInstance.callCustomServiceMethod();
    }

    // 可选:用@PostConstruct在Bean初始化完成后自动执行
    @PostConstruct
    private void init() {
        myCustomService.anyMethod();
    }

    private void callCustomServiceMethod() {
        myCustomService.anyMethod();
    }

    @Bean
    public ThreadPoolTaskExecutor jobLauncherTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(25);
        return executor;
    }
}

方案2:静态setter手动注入(应急用,不推荐)

如果一定要保留静态字段,可以添加一个带@Autowired的非静态setter方法,让Spring调用它来给静态变量赋值:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class App{
    private static Logger logger = LoggerFactory.getLogger(App.class);
    private static MyCustomService myCustomService;

    // Spring会自动调用这个setter方法注入实例
    @Autowired
    public void setMyCustomService(MyCustomService service) {
        App.myCustomService = service;
    }

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
        // 注意:必须等Spring上下文完全初始化后再调用,否则可能还是null
        myCustomService.anyMethod();
    }

    @Bean
    public ThreadPoolTaskExecutor jobLauncherTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(25);
        return executor;
    }
}

额外说明:关于scanBasePackages

其实你的项目结构完全不需要配置scanBasePackages——@SpringBootApplication默认会扫描当前类所在的包(com.project.name)及其所有子包,com.project.name.service是它的子包,所以你的MyCustomService早就被Spring扫描到了,注释掉scanBasePackages完全没问题。

内容的提问来源于stack exchange,提问作者Genaut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:15:37