1、先给所有的策略装配到一个枚举类
@Getter
@AllArgsConstructor
public enum CallbackTypeEnum {
ORDER_CALLBACK("order", "订单回调"),
PAYMENT_CALLBACK("payment", "支付回调"),
SHIPPING_CALLBACK("shipping", "物流回调");
private final String code;
private final String description;
public static CallbackTypeEnum getByCode(String code) {
for (CallbackTypeEnum value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
throw new IllegalArgumentException("未支持的回调类型: " + code);
}
}
2、写一个自定义注解,就是为了将枚举类的值跟匹配的handler连接
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface OrderStrategyType {
CallbackTypeEnum value();
}
策略类
public interface LogUpdateStrategy {
void updateLog(CallbackResult callbackResult);
}
实现类
@Component
@OrderStrategyType(CallbackTypeEnum.PAYMENT_CALLBACK)
public class PaymentCallbackStrategy implements LogUpdateStrategy {
@Override
public void updateLog(CallbackResult result) {
System.out.println("更新支付日志表, status: " + result.getStatus());
}
}
3、使用工厂模式,将匹配的枚举类的值跟handler放到一个map里随后放到内存中【核心】
@Component
public class LogUpdateStrategyFactory implements ApplicationContextAware {
private static final Map<CallbackTypeEnum, LogUpdateStrategy> STRATEGY_MAP = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
Map<String, LogUpdateStrategy> beans = applicationContext.getBeansOfType(LogUpdateStrategy.class);
beans.forEach((beanName, strategy) -> {
OrderStrategyType annotation = strategy.getClass().getAnnotation(OrderStrategyType.class);
if (annotation != null) {
STRATEGY_MAP.put(annotation.value(), strategy);
}
});
}
public LogUpdateStrategy getStrategy(CallbackTypeEnum type) {
LogUpdateStrategy strategy = STRATEGY_MAP.get(type);
if (strategy == null) {
throw new IllegalArgumentException("未找到对应的日志更新策略: " + type);
}
return strategy;
}
public LogUpdateStrategy getStrategyByCode(String typeCode) {
CallbackTypeEnum type = CallbackTypeEnum.getByCode(typeCode);
return getStrategy(type);
}
}
4、在使用的过程,只要得到map的key,即可在内存中得到对应的handler
@Component
public class CallbackLogContext {
@Autowired
private LogUpdateStrategyFactory strategyFactory;
public void handleCallback(CallbackResult callbackResult) {
String interfaceType = callbackResult.getInterfaceType();
LogUpdateStrategy strategy = strategyFactory.getStrategyByCode(interfaceType);
strategy.updateLog(callbackResult);
}
}
5、使用handler对需要处理的业务代码进行处理
@Component
@OrderStrategyType(CallbackTypeEnum.ORDER_CALLBACK)
public class OrderCallbackStrategy implements LogUpdateStrategy {
@Autowired
private OrderLogMapper orderLogMapper;
@Override
public void updateLog(CallbackResult result) {
String requestId = result.getRequestId();
String status = result.getStatus();
OrderLog orderLog = new OrderLog();
orderLog.setRequestId(requestId);
orderLog.setStatus(status);
orderLog.setUpdateTime(new Date());
orderLogMapper.updateByRequestId(orderLog);
System.out.println("更新订单日志表, requestId: " + requestId + ", status: " + status);
}
}
6、可以进一步将获取handler的过程进一步进行包装,对外只需要使用统一的类调用其的一个方法,就可以对业务代码进行处理
@RestController
@RequestMapping("/callback")
public class CallbackController {
@Autowired
private CallbackLogContext callbackLogContext;
@PostMapping("/notify")
public String handleCallback(@RequestBody CallbackResult callbackResult) {
try {
callbackLogContext.handleCallback(callbackResult);
return "success";
} catch (Exception e) {
return "error: " + e.getMessage();
}
}
}