抱歉,我对 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/