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
相关产品推荐
相关产品推荐

