SpringBoot优雅实现接口的多实现类方式详解

 更新时间:2025年10月21日 14:57:02   作者:一线大码  
这篇文章主要为大家详细介绍了SpringBoot优雅实现接口的多实现类方式的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

1. 样板代码

1.1. 支付类型枚举

package com.example.demo.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * 支付类型枚举
 *
 * @author wangbo
 */
@Getter
@AllArgsConstructor
public enum PaymentTypeEnum {
    ALIPAY("alipay", "支付宝"),
    WECHAT("wechat", "微信"),
    UNIONPAY("unionpay", "银联");

    private final String code;
    private final String name;
}

1.2. 支付服务接口

package com.example.demo.service;

import com.example.demo.enums.PaymentTypeEnum;

import java.math.BigDecimal;

/**
 * 支付服务
 *
 * @author wangbo
 */
public interface PaymentService {
    /**
     * 获取支付方式
     *
     * @return PaymentTypeEnum
     */
    PaymentTypeEnum getPaymentType();

    /**
     * 处理支付
     *
     * @param amount 金额
     */
    void processPayment(BigDecimal amount);
}

1.3. 支付服务实现类

package com.example.demo.service.impl;

import com.example.demo.enums.PaymentTypeEnum;
import com.example.demo.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 支付服务实现-支付宝支付
 *
 * @author wangbo
 */
@Slf4j
@Service
public class PaymentServiceAlipayImpl implements PaymentService {

    @Override
    public PaymentTypeEnum getPaymentType() {
        return PaymentTypeEnum.ALIPAY;
    }

    @Override
    public void processPayment(BigDecimal amount) {
        log.info("支付宝支付: " + amount);
    }
}
package com.example.demo.service.impl;

import com.example.demo.enums.PaymentTypeEnum;
import com.example.demo.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 支付服务实现-微信支付
 *
 * @author wangbo
 */
@Slf4j
@Service
public class PaymentServiceWechatImpl implements PaymentService {
    @Override
    public PaymentTypeEnum getPaymentType() {
        return PaymentTypeEnum.WECHAT;
    }

    @Override
    public void processPayment(BigDecimal amount) {
        log.info("微信支付: " + amount);
    }
}

1.4. 支付服务策略管理器

package com.example.demo.manager;

import com.example.demo.enums.PaymentTypeEnum;
import com.example.demo.service.PaymentService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 支付服务策略管理器
 *
 * @author wangbo
 */
@Component
@AllArgsConstructor
public class PaymentServiceStrategyManager {

    private final List<PaymentService> paymentServices;

    public PaymentService getPaymentService(PaymentTypeEnum paymentTypeEnum) {
        for (PaymentService paymentService : paymentServices) {
            if (paymentService.getPaymentType().equals(paymentTypeEnum)) {
                return paymentService;
            }
        }
        throw new IllegalArgumentException("不支持的支付方式: " + paymentTypeEnum.getName());
    }
}

2. 使用代码

订单处理中需要调用支付服务

2.1. 订单服务接口

package com.example.demo.service;

import com.example.demo.enums.PaymentTypeEnum;

import java.math.BigDecimal;

/**
 * 订单服务
 *
 * @author wangbo
 */
public interface OrderService {
    /**
     * 处理订单
     *
     * @param paymentTypeEnum 支付方式
     * @param amount          支付金额
     */
    void processOrder(PaymentTypeEnum paymentTypeEnum, BigDecimal amount);
}

2.2. 订单服务实现类

package com.example.demo.service.impl;

import com.example.demo.enums.PaymentTypeEnum;
import com.example.demo.manager.PaymentServiceStrategyManager;
import com.example.demo.service.OrderService;
import com.example.demo.service.PaymentService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

/**
 * 订单服务实现
 *
 * @author wangbo
 */
@Service
@AllArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final PaymentServiceStrategyManager paymentServiceStrategyManager;

    @Override
    public void processOrder(PaymentTypeEnum paymentTypeEnum, BigDecimal amount) {
        PaymentService paymentService = paymentServiceStrategyManager.getPaymentService(paymentTypeEnum);
        paymentService.processPayment(amount);
    }
}

3. 测试代码

package com.example.demo.controller;

import com.example.demo.enums.PaymentTypeEnum;
import com.example.demo.service.OrderService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

/**
 * @author wangbo
 * @since 2025/10/21
 */
@RestController
@AllArgsConstructor
public class OrderController {

    private final OrderService orderService;

    @GetMapping("/order")
    public String processOrder() {
        orderService.processOrder(PaymentTypeEnum.ALIPAY, BigDecimal.TEN);
        return "支付成功";
    }

    @GetMapping("/order1")
    public String processOrder1() {
        orderService.processOrder(PaymentTypeEnum.WECHAT, BigDecimal.TEN);
        return "支付成功";
    }

    @GetMapping("/order2")
    public String processOrder2() {
        orderService.processOrder(PaymentTypeEnum.UNIONPAY, BigDecimal.TEN);
        return "支付成功";
    }
}
  • http://localhost:8080/order
  • http://localhost:8080/order1
  • http://localhost:8080/order2

分别调用三次后,日志如下:

2025-10-21T12:01:11.144+08:00  INFO 32792 --- [demo] [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-21T12:01:11.144+08:00  INFO 32792 --- [demo] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2025-10-21T12:01:11.146+08:00  INFO 32792 --- [demo] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2025-10-21T12:01:11.170+08:00  INFO 32792 --- [demo] [nio-8080-exec-1] c.e.d.s.impl.PaymentServiceAlipayImpl    : 支付宝支付: 10
2025-10-21T12:01:21.053+08:00  INFO 32792 --- [demo] [nio-8080-exec-3] c.e.d.s.impl.PaymentServiceWechatImpl    : 微信支付: 10
2025-10-21T12:01:26.791+08:00 ERROR 32792 --- [demo] [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: 不支持的支付方式: 银联] with root cause

java.lang.IllegalArgumentException: 不支持的支付方式: 银联
    at com.example.demo.manager.PaymentServiceStrategyManager.getPaymentService(PaymentServiceStrategyManager.java:27) ~[main/:na]
    at com.example.demo.service.impl.OrderServiceImpl.processOrder(OrderServiceImpl.java:24) ~[main/:na]
    at com.example.demo.controller.OrderController.processOrder2(OrderController.java:35) ~[main/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:258) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:191) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:991) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:896) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.43.jar:6.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.9.jar:6.2.9]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.43.jar:6.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.9.jar:6.2.9]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.9.jar:6.2.9]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.2.9.jar:6.2.9]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.2.9.jar:6.2.9]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:116) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:398) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:903) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1769) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.43.jar:10.1.43]
    at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]

到此这篇关于SpringBoot优雅实现接口的多实现类方式详解的文章就介绍到这了,更多相关SpringBoot接口多实现类方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JVM回收跨代垃圾的方式详解

    JVM回收跨代垃圾的方式详解

    在Java堆内存中,年轻代和老年代之间存在的对象相互引用,假设现在要进行一次新生代的YGC,但新生代中的对象可能被老年代所引用的,为了找到新生代中的存活对象,不得不遍历整个老年代,这样明显效率很低下,那么如何快速识别并回收这种引用对象呢
    2024-02-02
  • Springboot的启动原理详细解读

    Springboot的启动原理详细解读

    这篇文章主要介绍了Springboot的启动原理详细解读,springboot项目一般都是打包成jar包直接运行main方法启动,当然也可以跟传统的项目一样打包war包放在tomcat里面启动.那么springboot怎么直接通过main方法启动呢,需要的朋友可以参考下
    2023-11-11
  • Java实现HTTP请求的4种方式总结

    Java实现HTTP请求的4种方式总结

    这篇文章主要给大家介绍了关于Java实现HTTP请求的4种方式,在java开发中,经常遇到需要调用第三方提供的接口服务的需求,文中给出了详细的代码示例,需要的朋友可以参考下
    2023-08-08
  • 详解Spring Boot 部署与服务配置

    详解Spring Boot 部署与服务配置

    本篇文章主要介绍了详解Spring Boot 部署与服务配置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Spring Data JPA中 in 条件参数的传递方式

    Spring Data JPA中 in 条件参数的传递方式

    这篇文章主要介绍了Spring Data JPA中 in 条件参数的传递方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot整合Netty的流程步骤

    SpringBoot整合Netty的流程步骤

    Netty是一个基于Java的开源网络应用框架,它提供了高性能、异步事件驱动的网络编程能力,Netty旨在帮助开发者构建高性能、高可靠性的网络应用程序,本文给大家详细介绍了SpringBoot整合Netty的流程步骤,需要的朋友可以参考下
    2023-09-09
  • Git工具 conflict冲突问题解决方案

    Git工具 conflict冲突问题解决方案

    这篇文章主要介绍了Git工具 conflict冲突问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • Java this、final等关键字总结

    Java this、final等关键字总结

    这篇文章主要对java中this、final等关键字进行了总结,需要的朋友可以参考下
    2017-04-04
  • 详解关于eclipse中使用jdk15对应javafx15的配置问题总结

    详解关于eclipse中使用jdk15对应javafx15的配置问题总结

    这篇文章主要介绍了详解关于eclipse中使用jdk15对应javafx15的配置问题总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Spring中的singleton和prototype的实现

    Spring中的singleton和prototype的实现

    这篇文章主要介绍了Spring中的singleton和prototype的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论