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

Spring Boot中父子类Service均加@Service致多实例,如何让子类成为唯一实例?

解决Spring Boot父子Service实例重复与定时任务重复执行问题

核心解决方案

直接移除核心库中父类ActivityRuleServiceImpl上的@Service注解,仅保留上层应用子类MyCompanyActivityRuleServiceImpl的@Service和@Primary注解。

问题根源

父类ActivityRuleServiceImpl和子类MyCompanyActivityRuleServiceImpl都标记了@Service,Spring会分别扫描并实例化这两个类,导致ActivityRuleService类型存在两个独立实例:

  • 核心库注入ActivityRuleService时可能拿到父类实例
  • 上层应用注入MyCompanyActivityRuleService时拿到子类实例
  • 父类中的@Scheduled定时任务会在两个实例上各自执行,因此出现每分钟执行两次、间隔仅1毫秒的情况

代码调整细节

核心库父类实现类修改

移除@Service注解,将其作为子类的基类而非独立可实例化的Bean:

@Slf4j
@CompileStatic
@SuppressWarnings("unused")
// 移除@Service注解,仅作为子类继承的基类
class ActivityRuleServiceImpl implements ActivityRuleService {
    // ... 原有业务逻辑
    
    @Scheduled(fixedDelay = 60000L)
    void activityRuleTask() {
        // 定时任务逻辑
    }
}

上层应用子类实现类保留注解

保留@Service让Spring实例化该类,同时通过@Primary确保它是ActivityRuleService类型的优先注入实例:

@Slf4j
@CompileStatic
@Primary
@Service
class MyCompanyActivityRuleServiceImpl extends ActivityRuleServiceImpl implements MyCompanyActivityRuleService {
    // ... 子类扩展的业务逻辑
}

效果验证

调整完成后,无论是核心库中通过@Autowired ActivityRuleService activityRuleService注入,还是上层应用中通过@Autowired MyCompanyActivityRuleService activityRuleService注入,拿到的都是同一个MyCompanyActivityRuleServiceImpl实例,定时任务也只会执行一次。

可通过以下代码验证实例唯一性:

@Autowired
ApplicationContext context;

// 打印所有ActivityRuleService类型的Bean信息
context.getBeansOfType(ActivityRuleService.class).forEach((beanName, bean) -> {
    System.out.println("Bean名称:" + beanName + ",实例类型:" + bean.getClass().getName());
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 19:42:38