数据库+SpringBean注入的方式实现策略模式--- 支付示例

在这里插入图片描述

  1. 首先定义个支付行为接口 PayStragtegy
package com.mbh.first_boot_demo.strategy;

/**
 * 支付行为接口
 * @description:
 * @author: mabh
 * @create: 2020/5/22 10:51 下午
 **/
public interface PayStrategy {

    /**
     * 调用支付
     */
    String toPayHtml();
}

  1. 继承接口实现阿里支付行为
package com.mbh.first_boot_demo.strategy.impl;

import com.mbh.first_boot_demo.strategy.PayStrategy;
import org.springframework.stereotype.Component;

/**
 * @description:
 * @author: mabh
 * @create: 2020/5/22 10:55 下午
 **/
@Component
public class AliPayStrategy implements PayStrategy {
    @Override
    public String toPayHtml() {
        System.out.println("调用阿里支付....");
        return "阿里巴巴";
    }
}

  1. 实现接口实现微信支付行为
package com.mbh.first_boot_demo.strategy.impl;

import com.mbh.first_boot_demo.strategy.PayStrategy;
import org.springframework.stereotype.Component;

/**
 * @description:
 * @author: mabh
 * @create: 2020/5/22 10:57 下午
 **/
@Component
public class WeixinPayStrategy implements PayStrategy {
    @Override
    public String toPayHtml() {
        System.out.println("执行微信支付.....");
        return "微信支付";
    }
}

  1. 定义支付上文类,获取具体支付策略行为
package com.mbh.first_boot_demo.strategy;

import com.mbh.first_boot_demo.utils.SpringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 支付上下文
 * @description:
 * @author: mabh
 * @create: 2020/5/22 11:06 下午
 **/
@Component
public class PayContextStrategy {


    /**
     * 获取具体策略实现
     * @param payCode
     * @return
     */
    public String toPayHtml(String payCode){
        if (StringUtils.isEmpty(payCode)) {
            return "payCode不能为空";
        }
        //查询数据库具体策略实现,我用Map代替
        String paymentChannel = getPaymentChannel(payCode);
        if(paymentChannel == null){
            return "没有查询到支付渠道";
        }
        //正常来说这个Bean名称是在数据库查询到的。这是用Map处理的。
        String strategyBeanId = paymentChannel;
        PayStrategy payStrategy = SpringUtils.getBean(strategyBeanId, PayStrategy.class);
        return payStrategy.toPayHtml();
    }


    /**
     *  查询数据库具体策略实现,我用Map代替
     * @param payCode
     * @return
     */
    private String getPaymentChannel(String payCode) {
        Map<String,String> map = new HashMap<>();
        map.put("wx_pay","weixinPayStrategy");
        map.put("ali_pay","aliPayStrategy");

        //key: 支付方式编码
        //value: 支付类型策略Bean
        return map.get(payCode);
    }
}

package com.mbh.first_boot_demo.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @description:
 * @author: mabh
 * @create: 2020/5/22 11:48 下午
 **/
public class SpringUtils implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        this.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 根据Class获取Bean
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 根据Bean名称获取Bean
     *
     * @param beanName
     * @return
     */
    public static Object getBean(String beanName) {
        return getApplicationContext().getBean(beanName);
    }

    /**
     * 根据Bean名称获取指定类型Class Bean
     * @param beanName
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String beanName,Class<T> clazz) {
        return getApplicationContext().getBean(beanName,clazz);
    }
}

使用方式直接在Controller 或 Serice 注入 PayContextStrategy类即可:

@Autowired
public PayContextStrategy payContextStrategy;

到这里就结束了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章