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

SpringBoot创建ScheduledTask提示需注册Long类bean及后续空指针问题

问题根源

第一个报错(找不到Long类型Bean)

你给ScheduledTask类加了@Component注解时,Spring会自动扫描实例化该类,但你的类只有带Long userId和Timer time两个参数的构造函数,Spring容器中没有对应类型的Bean可以注入到构造参数中,所以抛出找不到java.lang.Long类型Bean的错误。

第二个空指针报错

你手动用new ScheduledTask(1L, new Timer())创建实例时,该对象不归Spring容器管理,Spring不会自动注入你加了@Autowired注解的UserDao,所以userDao是null值,调用userDao.findById时就会触发空指针异常。

解决方案

推荐方案:调整构造函数,通过@Bean方法参数注入依赖

你可以把UserDao也加到构造函数参数中,@Bean方法的参数会被Spring自动注入对应类型的Bean,不需要依赖@Autowired:

  1. 调整ScheduledTask的构造函数:
public class ScheduledTask extends TimerTask {

    private UserDao userDao;
    private Long userId;
    private Timer time;

    // 把UserDao放到构造参数中,去掉@Autowired注解
    public ScheduledTask(UserDao userDao, Long userId, Timer time) {
        this.userDao = userDao;
        this.userId = userId;
        this.time = time;
    }

    @Override
    public void run() {
        Optional<User> userOptional = userDao.findById(userId);
        if (!userOptional.isPresent()) {
            time.cancel();
            return;
        }
        User user = userOptional.get();
        BigDecimal globalBalance = user.getGlobalBalance();
        user.setGlobalBalance(globalBalance.subtract(Constantes.RELIVRY_COMPANY_FEE));
        // 补充:修改完实体属性后需要调用save方法持久化到数据库,否则修改不会生效
        userDao.save(user);
    }
}
  1. 调整Application中的@Bean定义:
@Bean
ScheduledTask scheduledTask(UserDao userDao) {
    return new ScheduledTask(userDao, 1L, new Timer());
}

额外优化建议

如果你的定时任务没有特殊的动态创建需求,直接使用Spring自带的@Scheduled注解会更简单,不需要手动维护Timer和TimerTask实例,也不需要手动处理依赖注入问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:51:03