【问题标题】:How to use a specific Component impl based on method parameter value如何根据方法参数值使用特定的 Component impl
【发布时间】:2020-06-26 20:17:16
【问题描述】:

我正在学习 Spring Boot,我想为我的问题找到一个更优雅的解决方案。

在特定服务中,我需要根据 Enum 值调用正确的 impl。

现在我正在做这样的事情:

@Service
public class VehicleHandlerService {
  @Autowired
  private CarService carService; // implements VehicleService interface
  @Autowired
  private BusService busService; // implements VehicleService interface
  @Autowired
  private TruckService truckService; // implements VehicleService interface
  
  public Vehicle doSomething(VehicleType type) {
    return getService(type).doSomething();
  }

  // I might need have different Data types for specific Service here, like a CarData, BusData, TruckData, etc...
  public .???. otherMethod(VehicleType type, Data data) {
    return getService(type).otherMethod(data);
  }

  private VehicleService getService(VehicleType type) {
    if(VehicleType.CAR.equals(type)) {
      return carService;
    } else if(VehicleType.BUS.equals(type)) {
      return busService;
    } else if(VehicleType.TRUCK.equals(type)) {
      return truckService;
    }
    //throw exception
  }
}

我想知道我们是否有一种更类似于 Spring 的方式来做到这一点?就像注入地图一样:

@Autowired
private Map<VehicleType, VehicleService> services;

除了有方法之外,还要使用它。

如果我以后需要添加更多 VehicleService impl,我也必须继续手动添加它们。

你们如何在 Spring 上处理此类问题以避免重复代码和一堆 if/else?

欢迎任何可以让我学习 Spring 功能的建议!

【问题讨论】:

标签: java spring spring-boot


【解决方案1】:

您必须使所有 VehicleService bean 都可以自我识别。为此目的,我自己使用的一种方法是将这些信息添加到 bean 本身中。在您的情况下,可以使用以下附加方法增强 VehicleService 基类/接口

public interface VehicleService {
    /** Add this method for self discovery */
    VehicleType getVehicleType();

    /* ... other methods of VehicleService interface */
}

然后 VehicleHandlerService 可以修改为如下内容:

public class VehicleHandlerService {
    @Autowired
    private List<VehicleService> handlerServices;

    /* ... other methods for this service here ... */
    
    private VehicleService getService(VehicleType type) {
        return handlerServices.stream().filter(x -> x.getVehicleType().equals(type)).findFirst().get();
    }
}

这样,任何新的 bean 都会自动注入并被服务适当地使用。

【讨论】:

    猜你喜欢
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    相关资源
    最近更新 更多