假设我们希望实现以下需求:
- 支付方式(如支付宝、微信支付)可以动态切换。
- 支付方式配置从配置文件中加载,或者支持在数据库中动态更新。
- 配置文件或数据库中指定当前生效的支付方式。
步骤 1: 配置文件定义支付方式
我们可以在 application.yml
或 application.properties
中定义支付方式配置项,指定默认的支付方式。
# application.yml
payment:
defaultMethod: alipay
这里我们定义了一个 payment.defaultMethod
配置项,它用于指定当前选择的支付方式。假设我们有多个支付方式,默认支付方式是 alipay
。
步骤 2: 在 PaymentContext
中加载动态配置
为了根据配置动态选择支付方式,我们需要将配置文件中的 defaultMethod
读入,并根据它来确定使用哪个支付策略。可以通过 Spring 的 @Value
注解来注入配置项。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class PaymentContext {
private final Map<String, PaymentStrategy> paymentStrategies;
@Value("${payment.defaultMethod}")
private String defaultPaymentMethod;
public PaymentContext(Map<String, PaymentStrategy> paymentStrategies) {
this.paymentStrategies = paymentStrategies;
}
public void executePayment(double amount) {
// 根据配置的支付方式动态选择策略
PaymentStrategy strategy = paymentStrategies.get(defaultPaymentMethod);
if (strategy != null) {
strategy.pay(amount);
} else {
throw new IllegalArgumentException("Invalid payment method: " + defaultPaymentMethod);
}
}
}
在这个 PaymentContext
中,我们通过 @Value
注解将 application.yml
中的 payment.defaultMethod
配置项注入到 defaultPaymentMethod
变量中。然后在 executePayment
方法中,根据配置项选择对应的支付策略执行支付。
步骤 3: 动态更新支付方式(可选)
如果您希望在运行时动态切换支付方式,可以考虑将支付方式配置存储在数据库中。通过查询数据库中的配置项,可以灵活地更新支付方式。
假设我们有一个 PaymentConfig
表,包含 method_code
和 enabled
等字段来表示当前生效的支付方式。
@Entity
public class PaymentConfig {
@Id
private Long id;
private String methodCode;
private Boolean enabled;
// getters and setters
}
接着,可以通过 Spring Data JPA 访问数据库中的配置:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DynamicPaymentConfigService {
private final PaymentConfigRepository paymentConfigRepository;
@Autowired
public DynamicPaymentConfigService(PaymentConfigRepository paymentConfigRepository) {
this.paymentConfigRepository = paymentConfigRepository;
}
public String getActivePaymentMethod() {
List<PaymentConfig> activeConfigs = paymentConfigRepository.findByEnabled(true);
// 假设返回第一个启用的支付方式
if (!activeConfigs.isEmpty()) {
return activeConfigs.get(0).getMethodCode();
}
return null; // 如果没有配置,返回空
}
}
然后在 PaymentContext
中使用这个动态配置服务来更新支付方式:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class PaymentContext {
private final Map<String, PaymentStrategy> paymentStrategies;
private final DynamicPaymentConfigService dynamicPaymentConfigService;
@Autowired
public PaymentContext(Map<String, PaymentStrategy> paymentStrategies, DynamicPaymentConfigService dynamicPaymentConfigService) {
this.paymentStrategies = paymentStrategies;
this.dynamicPaymentConfigService = dynamicPaymentConfigService;
}
public void executePayment(double amount) {
// 从数据库或配置中获取当前启用的支付方式
String activePaymentMethod = dynamicPaymentConfigService.getActivePaymentMethod();
if (activePaymentMethod != null) {
PaymentStrategy strategy = paymentStrategies.get(activePaymentMethod);
if (strategy != null) {
strategy.pay(amount);
} else {
throw new IllegalArgumentException("Invalid payment method: " + activePaymentMethod);
}
} else {
throw new IllegalStateException("No active payment method configured.");
}
}
}
通过上述方式,我们可以从数据库动态获取当前启用的支付方式,并在执行支付时应用它。
步骤 4: 控制器调用(不暴露支付方式)
在控制器层面,我们依然只关心执行支付,而不会暴露具体的支付方式。支付方式的选择完全依赖于配置文件或数据库中的设置。
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/payment")
public class PaymentController {
private final PaymentContext paymentContext;
@Autowired
public PaymentController(PaymentContext paymentContext) {
this.paymentContext = paymentContext;
}
@PostMapping("/pay")
public String pay(@RequestParam double amount) {
try {
paymentContext.executePayment(amount);
return "支付成功!";
} catch (IllegalArgumentException | IllegalStateException e) {
return e.getMessage();
}
}
}
总结
- 动态配置:通过
application.yml
或数据库存储支付方式配置,能够动态切换支付方式而不暴露给前端请求 URL。 - 灵活扩展:新增支付方式时,只需要实现一个新的支付策略类,并在配置文件或数据库中添加相应的配置,无需修改控制器或核心业务逻辑。
- 安全性:通过不暴露支付方式具体实现,只提供支付功能接口,增加了安全性和封装性。
这种设计不仅能够支持多种支付方式,还能够根据配置灵活切换支付策略,适应不同的支付场景。
标签:springboot,方式,配置,最佳,paymentStrategies,支付,import,设计模式,public From: https://www.cnblogs.com/tyxy/p/18534129