开发者

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

目录
  • 1. 样板代码
    • 1.1. 支付类型枚举
    • 1.2. 支付服务接口
    • 1.3. 支付服务实现类
    • 1.4. 支付服务策略管理器
  • 2. 使用代码
    • 2.1. 订单服务接口
    • 2.2. 订单服务实现类
  • 3. 测试代码

    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;
    
    /**
     http://www.devze.com* 支付服务策略管理器
     *
     * @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 proce编程客栈ssOrder(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(AppjslicationFilterChain.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.jarandroid: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]

      IaFvXxu  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接口多实现类方式内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜