java - 如何根据输入值动态注入(inject)或获取bean?

标签 java spring spring-boot dependency-injection

抱歉,我对 Spring 还很陌生。我想根据用户的输入值动态注入(inject)或获取bean。

例如:

public interface PaymentGateway {}

public class PayPal implement PaymentGateway {}

public class Stripe implement PaymentGateway {}

public class Square implement PaymentGateway {}

public class PaymentService {

    @Autowired
    private final PaymentGateway gateway;

    // TODO

}

我让用户选择一个支付网关(PayPal、Stripe 或 Square)并注入(inject)一个 PaymentGateway 进行处理。如何动态注入(inject)或获取bean?

非常感谢!

最佳答案

我认为您有多种方法可以做到这一点。

其中之一就是以下一个。

我看到 PaymentGateway 它是一个 private final,它强制您使用构造函数注入(inject),即使您将 @Autowired 放在成员(member)字段。这意味着您可以通过以下方式将 PaymentService 创建为 bean:

@Bean
public PaymentService paymentService(PaymentGateway gw) {
   return new PaymentService(gw);
}

在这里,您可以让您的客户使用任何 PaymentGateway 实现所需的内容。

编辑

此后的编辑是为了引入 Dispatcher 来查找正确的 PaymentGateway bean。

首先引入一个枚举类型,比如说

enum PmtGatewayType {
PayPal,
Stripe,
Square
}

现在,在 PaymentGateway 接口(interface)中添加如下方法:

public boolean accept(PmtGatewayType pmtGatewayType);

并按以下方式实现:

class Stripe implements PaymentGateway {

private PmtGatewayType gwType;

@Override
public boolean accept(PmtGatewayType pmtGwType) {

   return gwType.equals(pmtGwType);

}

现在,您可以创建另一个名为 PmtGwDispatcher 的类,您将在其中注入(inject)所有 PaymentGateway bean 的 List,如下所示:

@Component
class PmtGwDispacher {

@Autowired
private List<PaymentGateway> pmtGateways;

public PaymentGateway select(PmtGatewayType gwType) {

PaymentGateway gw = pmtGateways.stream().filter(gw -> gw.accept(gwType)).findFirst().get();

    if(gw == null) {
       throw new IllegalArgumentException("The provided gateway type is invalid");
    }
    }

现在,在 PaymentService 中,您可以注入(inject) PmtGwDispatcher 并使用它。

该解决方案有点复杂,但它尊重 SOLID 原则。每个组件都遵循 SRP,每次您需要添加新的 PaymentGateway 时,您必须在枚举中仅添加一个条目并添加新网关的实现。

关于java - 如何根据输入值动态注入(inject)或获取bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61306376/

相关文章:

spring-boot - Spring Cloud Streams-以下方法不存在

java - 使用服务用户或公共(public)用户保护 REST 端点

java - Thread.exit 行 : not available. 未找到源。编辑源查找路径...?

java - 为什么 Spring 不将映射注入(inject)到子 Struts 2 Action 类中,而是注入(inject)父对象的对象?

java - Spring 在 Java 类中单击按钮

java - hibernate 二级缓存逐出特定实体

java - Spring创建单例的多个实例?

java - 在 Jenkins 上部署 Spring Boot 应用程序

Java 反射和 scala 类

java - 由于 EXCEPTION_ACCESS_VIOLATION,我公司的软件无法运行