需求:spring boot 全家桶下有多种支付方式(如:支付宝,微信,银联,通联,苹果),不用if..elseswitch,使用涉及模式-策略模式和工厂模式解决支付方式选择问题
案例请看 后面

主要使用了Spring的 ApplicationContextAware ,BeanFactoryPostProcessor,BeanPostProcessor

SpringBeanUtil 工具类,springboot获取Spring容器中的bean

spring提供了ApplicationContextAware接口,ApplicationContextAware接口的 Bean在被初始之后,可以取得相对应的资源,这个类可以直接获取spring 配置文件中 所有引用(注入)到的bean对象

实现ApplicationContextAware接口,并加入@Component注解,让spring扫描到该bean

package com.foxwho.demo.startegymode.util;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/*** Bean工具类* springboot获取Spring容器中的bean* 在非spring管理的类中获取spring注册的bean*/
@Component
public class SpringBeanUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {if (applicationContext == null) {applicationContext = context;}}/*** 获取applicationContext* @return*/public static ApplicationContext getApplicationContext() {return applicationContext;}/*** 通过name获取 Bean* @param name* @return*/public static Object getBean(String name) {return applicationContext.getBean(name);}/*** 通过class获取Bean.* @param clazz* @param <T>* @return*/public static <T> T getBean(Class<T> clazz) {return applicationContext.getBean(clazz);}/*** 通过name,以及Clazz返回指定的Bean* @param name* @param clazz* @param <T>* @return*/public static <T> T getBean(String name,Class<T> clazz){return applicationContext.getBean(name, clazz);}}

BeanFactoryPostProcessor和BeanPostProcessor这两个接口都是初始化bean时对外暴露的入口之一,和Aware类似

package com.foxwho.demo.startegymode.handler;import com.foxwho.demo.startegymode.constant.PayConstant;
import com.foxwho.demo.startegymode.scaner.ClassScaner;
import com.google.common.collect.Maps;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;import java.util.Map;@Component
@SuppressWarnings("unchecked")
public class HandlerProcessor implements BeanFactoryPostProcessor {/*** 包路径*/private static final String HANDLER_PACKAGE = "com.foxwho.demo.startegymode.handler.concrete";/*** 扫描@HandlerPayId,初始化HandlerContext,将其注册到spring容器** @param beanFactory bean工厂* @see HandlerPayId* @see HandlerContext*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {Map<Integer, Class> handlerMap = Maps.newHashMapWithExpectedSize(PayConstant.COUNT_PAY_ID);//扫描指定包路径下类ClassScaner.scan(HANDLER_PACKAGE, HandlerPayId.class).forEach(clazz -> {// 获取注解中的类型值int type = ((HandlerPayId) clazz.getAnnotation(HandlerPayId.class)).payId();// 将注解中的类型值作为key,对应的类作为value,保存在Map中handlerMap.put(type, clazz);});// 初始化HandlerContext,将其注册到spring容器中HandlerContext context = new HandlerContext(handlerMap);//注册到spring容器中beanFactory.registerSingleton(HandlerContext.class.getName(), context);}}

spring boot 全家桶下有多种支付方式案例-- IF ELSE 的实现方式

案例源码:https://github.com/foxiswho/java-spring-boot-strategy-mode-demo

接口 PayOldService

package com.foxwho.demo.startegymode.service;import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;public interface PayOldService {/*** 根据订单的不同类型作出不同的处理** @param dto 订单实体* @return PayDto 处理后实体*/PayDto handle(OrderDto dto);}

接口实现类 PayOldServiceImpl

package com.foxwho.demo.startegymode.service.impl;import com.foxwho.demo.startegymode.constant.PayConstant;
import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;
import com.foxwho.demo.startegymode.service.PayOldService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;@Service
public class PayOldServiceImpl implements PayOldService {@Overridepublic PayDto handle(OrderDto dto) {PayDto payDto = new PayDto();//拷贝对象BeanUtils.copyProperties(dto, payDto);if (PayConstant.PAY_ID_ALIPAY == dto.getPayId()) {//调用支付宝SDKpayDto.setForm("这是 ifelse.switch 支付宝表单");} else if (PayConstant.PAY_ID_WECHAT == dto.getPayId()) {//调用 微信SDKpayDto.setForm("这是 ifelse.switch 微信表单");} else if (PayConstant.PAY_ID_ALLINPAY == dto.getPayId()) {//调用 通联SDKpayDto.setForm("这是 ifelse.switch 通联表单");} else {//调用支付宝SDKpayDto.setForm("这是 ifelse.switch 支付宝表单");}return payDto;}
}

如果只有3种支付方式,这是没有问题的,更多种支付方式呢,容易造成 看代码类,维护代码也累,有可能此类会有 大于1万行的情况

案例源码:https://github.com/foxiswho/java-spring-boot-strategy-mode-demo

以下是if.else访问案例

支付宝

http://localhost:8080/old/alipay

输出

{"no":"N1556172818764","payId":10000,"form":"这是 ifelse.switch 支付宝表单"}

微信支付

http://localhost:8080/old/wechat

输出

{"no":"N1556172909399","payId":10001,"form":"这是 ifelse.switch 微信表单"}

通联支付

http://localhost:8080/old/allinpay

输出

{"no":"N1556172950228","payId":10002,"form":"这是 ifelse.switch 通联表单"}

spring boot 全家桶下有多种支付方式案例–策略模式实现,不使用IF ELSE

策略模式
https://www.cnblogs.com/lewis0077/p/5133812.html

案例源码:https://github.com/foxiswho/java-spring-boot-strategy-mode-demo

策略接口 IStrategyPayService

package com.foxwho.demo.startegymode.service;import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;/*** 策略接口*/
public interface IStrategyPayService {/*** 根据订单的不同类型作出不同的处理** @param dto 订单实体* @return PayDto 处理后实体*/PayDto handle(OrderDto dto);}

接口实现类 StrategyPayServiceImpl

package com.foxwho.demo.startegymode.service.impl;
import com.foxwho.demo.startegymode.handler.AbstractHandler;
import com.foxwho.demo.startegymode.handler.StrategyHandlerContext;
import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;
import com.foxwho.demo.startegymode.service.IStrategyPayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class StrategyPayServiceImpl implements IStrategyPayService {@Autowiredprivate StrategyHandlerContext handlerContext;@Overridepublic PayDto handle(OrderDto dto) {AbstractHandler handler = handlerContext.getInstance(dto.getPayId());return handler.handler(dto);}
}

策略上下文 StrategyHandlerContext 获取实例化后类

package com.foxwho.demo.startegymode.handler;
import com.foxwho.demo.startegymode.util.SpringBeanUtil;
import java.util.Map;/*** 策略上下文*/
@SuppressWarnings("unchecked")
public class StrategyHandlerContext {private Map<Integer, Class> handlerMap;public StrategyHandlerContext(Map<Integer, Class> handlerMap) {this.handlerMap = handlerMap;}/*** 获取实例化后对象** @param payId* @return*/public AbstractHandler getInstance(Integer payId) {if (null == payId) {throw new IllegalArgumentException("payId not null : " + payId);}Class clazz = handlerMap.get(payId);if (clazz == null) {throw new IllegalArgumentException("not found handler for payId: " + payId);}return (AbstractHandler) SpringBeanUtil.getBean(clazz);}
}

支付ID注解 HandlerPayId

package com.foxwho.demo.startegymode.handler;
import com.foxwho.demo.startegymode.constant.PayConstant;
import java.lang.annotation.*;@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface HandlerPayId {int payId() default PayConstant.PAY_ID_ALIPAY;}

抽象业务处理动作 AbstractHandler

package com.foxwho.demo.startegymode.handler;
import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;public abstract class AbstractHandler {abstract public PayDto handler(OrderDto dto);
}

具体支付业务处理实现类 - 支付宝

package com.foxwho.demo.startegymode.handler.concrete;import com.foxwho.demo.startegymode.constant.PayConstant;
import com.foxwho.demo.startegymode.handler.AbstractHandler;
import com.foxwho.demo.startegymode.handler.HandlerPayId;
import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;/*** 支付宝*/
@Component
@HandlerPayId(payId = PayConstant.PAY_ID_ALIPAY)
public class ConcreteStrategyAliPayHandler extends AbstractHandler {@Overridepublic PayDto handler(OrderDto dto) {PayDto payDto = new PayDto();//拷贝对象BeanUtils.copyProperties(dto, payDto);//调用 支付宝SDKpayDto.setForm("这是支付宝表单");return payDto;}
}

具体支付业务处理实现类 - 微信

package com.foxwho.demo.startegymode.handler.concrete;import com.foxwho.demo.startegymode.constant.PayConstant;
import com.foxwho.demo.startegymode.handler.AbstractHandler;
import com.foxwho.demo.startegymode.handler.HandlerPayId;
import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;/*** 微信*/
@Component
@HandlerPayId(payId = PayConstant.PAY_ID_WECHAT)
public class ConcreteStrategyWeChatHandler extends AbstractHandler {@Overridepublic PayDto handler(OrderDto dto) {PayDto payDto = new PayDto();//拷贝对象BeanUtils.copyProperties(dto, payDto);//调用 微信SDKpayDto.setForm("这是微信表单");return payDto;}
}

具体支付业务处理实现类 - 通联

package com.foxwho.demo.startegymode.handler.concrete;import com.foxwho.demo.startegymode.constant.PayConstant;
import com.foxwho.demo.startegymode.handler.AbstractHandler;
import com.foxwho.demo.startegymode.handler.HandlerPayId;
import com.foxwho.demo.startegymode.model.OrderDto;
import com.foxwho.demo.startegymode.model.PayDto;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;/*** 通联*/
@Component
@HandlerPayId(payId = PayConstant.PAY_ID_ALLINPAY)
public class ConcreteStrategyAllInPayHandler extends AbstractHandler {@Overridepublic PayDto handler(OrderDto dto) {PayDto payDto = new PayDto();//拷贝对象BeanUtils.copyProperties(dto, payDto);//调用 通联SDKpayDto.setForm("这是通联表单");return payDto;}
}

核心部分就是这么多了,其他的就是控制器调用了,具体的看源码
案例源码:https://github.com/foxiswho/java-spring-boot-strategy-mode-demo

策略模式访问连接

支付宝

http://localhost:8080/alipay

输出

{"no":"N1556172818764","payId":10000,"form":"这是支付宝表单"}

微信支付

http://localhost:8080/wechat

输出

{"no":"N1556172909399","payId":10001,"form":"这是微信表单"}

通联支付

http://localhost:8080/allinpay

输出

{"no":"N1556172950228","payId":10002,"form":"这是通联表单"}

流程图

来源:
https://www.jianshu.com/p/71feb016ac05
https://www.jianshu.com/p/4145f507f3e7
https://www.cnblogs.com/s648667069/p/6489557.html
https://blog.csdn.net/qq_28070019/article/details/83624380
https://blog.csdn.net/u010889390/article/details/82178929
http://www.cnblogs.com/tflowingcloud/p/8443010.html
https://www.jianshu.com/p/a90a3e617ba6

springboot获取Spring容器中的bean(ApplicationContextAware接口的应用)避免过多的或不用if..else,switch相关推荐

  1. 【SpringBoot】在普通类中获取spring容器中的bean

    这段时间公司搞封闭开发,做一个联通总部的客服系统项目,是基于springboot的.在开发工程中遇到一个页面datagrid数据排序的功能,因为有多个表的数据都要用到排序功能,于是我就写了一个排序功能 ...

  2. SpringBoot 之 普通类获取Spring容器中的bean

    SpringBoot 之 普通类获取Spring容器中的bean 转载于:https://www.cnblogs.com/lwmp/p/8892927.html

  3. 在普通类中获取spring容器中的bean

    在普通类中获取spring容器中的bean 1.工具类 package com.itheima.hchat.util;import org.springframework.beans.BeansExc ...

  4. Spring Boot中普通类获取Spring容器中的Bean

    我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,自己动手n ...

  5. spring boot获取spring容器中的bean对象

    我们知道如果我们要在一个类使用  spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接 ...

  6. java静态方法中获取spring容器中的bean

    获取上下文工具类: package com.hikvision.pvia.kafka.utils;import org.springframework.beans.BeansException; im ...

  7. 在servlet中或者在filter中获取spring容器中的bean

    1 配置spring文件 <bean id="hibernateTemplate" class="org.springframework.orm.hibernate ...

  8. 工具类:获取 spring 容器中 bean

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. package com.orange.utils;import org.springframewor ...

  9. 解决无法注入spring容器,获取不到spring容器中的bean问题

    解决无法注入spring容器,获取不到spring容器中的bean问题 前两天工作中遇到一个问题,收到的需求是根据logbak日志实现通过过滤错误日志发送预警邮件到邮箱,logback自定义实现类如下 ...

  10. Spring容器中的Bean是否会被GC呢?

    Spring容器中的Bean是否会被GC呢?最近好几次被校招实习生问及,对于初学者来说,这应该是一个有意思的问题,鉴于此,笔者顺便写个这个文档. 1.Spring容器中Bean的作用域 当通过Spri ...

最新文章

  1. 【linux系统】IK分词器安装
  2. oracle+事务开始+结束,Oracle事务和对象上集(视图、索引)
  3. 本文以H264视频流为例,讲解解码流数据的步骤。
  4. 微软BUG Bounty悬赏项目扩展至.NET Core和ASP.NET Core
  5. (100)FPGA单沿和双沿采样(下降沿采样)
  6. Oracle包和包体
  7. 解决CodeBlocks中文不显示的问题
  8. 让我们一起ML吧(一)聚类分析
  9. [Cocos2d-x] init()和onEnter()方法的区别
  10. 读《别闹了,费曼先生》 时的几点想法
  11. 原生js实现动态生成表格
  12. python写文件格式转换程序_有趣的python小程序——图片格式转换
  13. Ubuntu、ros快速安装
  14. 电脑硬件常见故障维修技巧
  15. windows启动时自动运行程序四种方法(登录或不登录都可以的)
  16. 傅里叶Fourier变换fft-python-scipy-幅值-辐角-相位(一)
  17. 了解抖音小店店铺装修功能以及条件
  18. 关于路由器中家长控制和上网控制的设置
  19. TPLINK AC650双频高增益无线USB网卡 TL-WDN5200H免驱版 Ubuntu16.04 安装
  20. 什么是xmlhttp

热门文章

  1. [编写高质量代码:改善java程序的151个建议]建议66 asList方法产生的List对象不可更改...
  2. 深入浅出插入类排序算法(直接插入, 折半插入, 希尔排序)
  3. 漫谈 Clustering (番外篇): Expectation Maximization
  4. 计算机科学现代教育,现代教育技术教程-计算机科学教育.pdf
  5. sap未分摊差异怎么处理_MM采购中形成的差异
  6. 拓端tecdat|使用R语言进行多项式回归、非线性回归模型曲线拟合
  7. java struts2 例子_java struts2入门学习实例--用户注册和用户登录整合
  8. 原python基础概念整理_python基础知识脉络梳理总结
  9. linux fopen文件失败,fopen自动创建文件失败(文件路径检查创建)
  10. 深度学习(二):传统神经网络