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

优化从实现同一接口的各Service中调用方法的方案

简化多Shape服务并行查询的实现方案

你当前通过自定义ShapeTask实现并行查询各Shape仓库数据,但新增方法时需要重复创建对应Task类,导致冗余代码过多。下面是几种简化方案,既能保留并行查询能力,又能大幅降低后续扩展的成本。

方案1:用CompletableFuture替代自定义Task

Java 8引入的CompletableFuture可以直接通过方法引用创建异步任务,无需手动实现Callable接口,完全去掉ShapeTask类,简化代码结构。

修改后的TestService代码:

@Service
@RequiredArgsConstructor
public class TestService {
    private final ShapeServiceFacade facade;
    private final ExecutorService executorService;

    public List<ShapeEntity> getAll() throws ExecutionException, InterruptedException {
        List<CompletableFuture<List<ShapeEntity>>> futures = facade.getServices().stream()
                .map(service -> CompletableFuture.supplyAsync(service::getAll, executorService))
                .toList();

        // 等待所有任务完成并合并结果
        return futures.stream()
                .map(CompletableFuture::join)
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }
}

说明:

  • 用CompletableFuture.supplyAsync结合方法引用service::getAll,替代自定义的ShapeTask
  • 流式API简化集合操作,减少冗余循环代码
  • join()方法等价于future.get(),但无需显式处理受检异常(可全局捕获处理)

方案2:将通用并行逻辑封装到Facade

把并行执行逻辑封装到ShapeServiceFacade中,新增方法时仅需在Facade中添加包装方法,无需修改调用端代码,彻底解决扩展时的重复劳动问题。

修改后的ShapeServiceFacade:

@Service
public class ShapeServiceFacade {
    private final Map<String, ShapeServicesInterface> shapeServices;
    private final ExecutorService executorService;

    // 注入所有Shape服务和线程池
    public ShapeServiceFacade(Set<ShapeServicesInterface> allServices, ExecutorService executorService) {
        this.shapeServices = allServices.stream()
                .collect(Collectors.toMap(ShapeServicesInterface::getName, Function.identity()));
        this.executorService = executorService;
    }

    public List<ShapeServicesInterface> getServices() {
        return new ArrayList<>(shapeServices.values());
    }

    // 通用并行执行模板方法,接收方法引用即可执行对应逻辑
    private <T> List<T> executeParallel(Function<ShapeServicesInterface, List<T>> methodExtractor) {
        return getServices().stream()
                .map(service -> CompletableFuture.supplyAsync(() -> methodExtractor.apply(service), executorService))
                .map(CompletableFuture::join)
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }

    // 对应原有的getAll方法
    public List<ShapeEntity> getAllShapes() {
        return executeParallel(ShapeServicesInterface::getAll);
    }

    // 新增方法示例:获取所有激活状态的Shape
    public List<ShapeEntity> getActiveShapes() {
        return executeParallel(ShapeServicesInterface::getActive);
    }
}

简化后的TestService:

@Service
@RequiredArgsConstructor
public class TestService {
    private final ShapeServiceFacade facade;

    public List<ShapeEntity> getAll() {
        return facade.getAllShapes();
    }

    // 新增方法直接调用Facade封装好的逻辑
    public List<ShapeEntity> getActive() {
        return facade.getActiveShapes();
    }
}

扩展流程:

  1. 在ShapeServicesInterface中新增方法(如List<ShapeEntity> getActive();)
  2. 在各Service实现类中实现该方法
  3. 在ShapeServiceFacade中添加调用executeParallel的包装方法即可

完全无需创建新的Task类,也不用修改调用端逻辑,扩展成本极低。

方案3:Spring环境下用@Async注解简化(可选)

如果项目基于Spring,可以利用@Async注解自动处理异步逻辑,无需手动管理线程池:

  1. 开启异步支持:
@Configuration
@EnableAsync
public class AsyncConfig {
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(8);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("ShapeAsync-");
        executor.initialize();
        return executor;
    }
}
  1. 修改接口方法为异步返回:
public interface ShapeServicesInterface {
    @Async
    CompletableFuture<List<ShapeEntity>> getAll();
    String getName();
}
  1. 实现类无需额外修改:
@Service
@RequiredArgsConstructor
public class CircleEntityService implements ShapeServicesInterface {
    private final CircleEntityRepository circleEntityRepository;

    @Override
    public CompletableFuture<List<ShapeEntity>> getAll() {
        return CompletableFuture.completedFuture(new ArrayList<>(circleEntityRepository.findAll()));
    }

    @Override
    public String getName() {
        return "circle";
    }
}
  1. 调用端简化:
@Service
@RequiredArgsConstructor
public class TestService {
    private final ShapeServiceFacade facade;

    public List<ShapeEntity> getAll() {
        return facade.getServices().stream()
                .map(ShapeServicesInterface::getAll)
                .map(CompletableFuture::join)
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }
}

这种方式由Spring统一管理异步任务,无需手动处理线程池,适合Spring环境下的快速开发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:05:30