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

使用JobRunr调度抽象类子类Lambda任务时遇Bean冲突问题求助

JobRunr调度任务遇到NoUniqueBeanDefinitionException的解决方向

你当前的代码在使用JobRunr结合Spring调度任务时触发了org.springframework.beans.factory.NoUniqueBeanDefinitionException,异常核心原因是Spring容器中存在Task1、Task2两个Task类型的实现类,无法确定要注入的唯一Bean。你的推测——JobRunr序列化时识别抽象类而非具体子类——是准确的,以下是具体解决思路:

解决方向

1. 直接调度具体子类Bean

放弃通过抽象类列表调用的方式,直接注入并引用具体的子类实例,从根源避免多态带来的序列化和Bean注入问题:

@Component
public class TaskExecutionListener implements ApplicationListener<TaskEvent> {
    private final Task1 task1;
    private final Task2 task2;

    // 构造注入具体子类Bean
    public TaskExecutionListener(Task1 task1, Task2 task2) {
        this.task1 = task1;
        this.task2 = task2;
    }

    @Override
    public void onApplicationEvent(TaskEvent event) {
        // 直接调度具体子类的process方法
        BackgroundJob.enqueue(() -> task1.process());
    }
}

2. 配置JobRunr序列化支持多态类型

如果必须保留抽象类的设计,需要配置JobRunr的序列化机制,让它能正确识别并序列化具体子类:

  • 给抽象类Task添加Jackson多态注解,明确子类类型:
    import com.fasterxml.jackson.annotation.JsonTypeInfo;
    import com.fasterxml.jackson.annotation.JsonSubTypes;
    
    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
    @JsonSubTypes({
        @JsonSubTypes.Type(value = Task1.class, name = "task1"),
        @JsonSubTypes.Type(value = Task2.class, name = "task2")
    })
    abstract class Task {
        abstract void process();
    }
    
  • 配置JobRunr使用Jackson作为序列化器,确保Spring能正确反序列化具体子类:
    @Bean
    public JobScheduler jobScheduler(JacksonJsonSerializer jacksonJsonSerializer, DataSource dataSource, ApplicationContext applicationContext) {
        return JobRunr.configure()
                .useJobActivator(new SpringJobActivator(applicationContext))
                .useJsonSerializer(jacksonJsonSerializer)
                .useStorageProvider(SqlStorageProviderFactory.sqlStorageProvider(dataSource))
                .initialize()
                .createJobScheduler();
    }
    

3. 避免在Lambda中引用集合元素

你当前代码中tasks.get(0)引用的是集合中的抽象类实例,JobRunr序列化时无法精准识别具体子类,Spring在恢复Bean时就会因为找不到唯一TaskBean报错。建议直接引用具体Bean实例,而非集合中的抽象类对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:21:08