业务代码:基于spring的银行支付接口模型实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38331606/article/details/85063724

1.业务逻辑

    当用户选择某一特定商品后,点击支付按钮;跳转到对应的支付页面,在用户选择对应的支付银行方式后,在页面实现对应的优惠信息。同时点击支付后,根据银行对应的报文要求,进行支付。

2.逻辑分析

3.技术点:

工厂模式,反射,spring手动注入,面向对象思想

3.支付接口

//支付接口
public interface Strategy {
    
    public BigDecimal calRecharge(Integer goodsId , Integer channelId);

}

4.实现类1

@Pay(channelId=1)
public class CCBBankServiceImpl implements Strategy {

    @Override
    public BigDecimal calRecharge(Integer goodsId, Integer channelId) {
        
        IAnniversaryService anniversaryDao = (IAnniversaryService) InjectionByHandUtil.getBean(IAnniversaryService.class);
        String num = anniversaryDao.selectUserNameByLoginName("ssss");
        
        BigDecimal goodPrice = new BigDecimal(10000);//商品价格
        BigDecimal discount = new BigDecimal(0.1);//银行折扣信息
        return goodPrice.multiply(discount);//返回真实价格
    }

}

5.实现类2

@Pay(channelId=2)
public class ICBCBankServiceImpl implements Strategy {
    
    
    @Override
    public BigDecimal calRecharge(Integer goodsId, Integer channelId) {
        BigDecimal goodPrice = new BigDecimal(10000);//商品价格
        BigDecimal discount = new BigDecimal(0.99);//银行折扣信息
        return goodPrice.multiply(discount);//返回真实价格
    }
}

6.pay注解:用于表明该实现类和具体银行处理方式之间的关系

@Target(ElementType.TYPE)//位置:注解在类文件中生效
@Retention(RetentionPolicy.RUNTIME)//声明周期:
  /*RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
    RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
    RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;*/
public @interface Pay {//定义一个注解,用于标识对应的具体银行的实现类
    int channelId();
}

7.工厂类:通过反射的方式,在加载时,自动配置支付通道id和对应支付方式之间的关系

//工厂模式用于创建具体的银行实现类
public class StrageFactory {
    private static StrageFactory factory = new StrageFactory();//饿汉式不存在线程安全问题;懒汉式-双重锁检查机制处理
    private StrageFactory() {}//私有构造方法
    public static StrageFactory getInstance(){return factory;}
    
    private static Map<Integer,String> bankMap = new HashMap<Integer,String>();
    static{
        //bankMap.put(1, "com.lx.pay.ICBCBankServiceImpl");//扩展性差
        Reflections reflection = new Reflections("com.lx.pay.service.impl");//使用Reflections工具类扫描对应包下的注解
        Set<Class<?>> classSet = reflection.getTypesAnnotatedWith(Pay.class);//获取在类文件头部的pay注解
        for(Class<?> c : classSet){//便利有Pay注解的class文件
            Pay pay = (Pay)c.getAnnotation(Pay.class);//获取该包下的有Pay注解的class文件中的Pay注解信息
            bankMap.put(pay.channelId(), c.getCanonicalName());//该class文件中定义的注解channelId值
        }
    }
    
    public Strategy create(Integer channelId) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
        Class clazz = Class.forName(bankMap.get(channelId));
        return (Strategy)clazz.newInstance();
    }
    
}

    <dependency>
        <groupId>org.reflections</groupId>
        <artifactId>reflections</artifactId>
        <version>0.9.10</version>
      </dependency>

8.支付模块对外接口,供外部调用

public class PayContext {//支付模块对外提供的接口,供外部调用
    public BigDecimal calRecharge(Integer goodsId , Integer channelId) throws Exception{
        StrageFactory factory = StrageFactory.getInstance();
        Strategy strategy = factory.create(channelId);
        return strategy.calRecharge(goodsId, channelId);
    }
}

9.工具类,用于注入已new方式生成的对象的spring实例对象

public class InjectionByHandUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }
    public static Object getBean(Class c){
        return applicationContext.getBean(c);
    }
}

      <!--Spring中bean获取的工具类-->
    <bean id="injectionByHandUtil" class="com.wpao.shop.util.InjectionByHandUtil" />

10.外部调用

@Controller
public class PayTestController {

    Logger logger = Logger.getLogger(this.getClass());
    
    /*@Resource
    private PayContext context;*/
    
    
    @RequestMapping("/pay")
    public String anniversary() throws Exception {
        PayContext context = new PayContext();
        BigDecimal res = context.calRecharge(1, 1);
        System.out.println("***:"+res);
        return "user/workshow";
    }
    
}

猜你喜欢

转载自blog.csdn.net/qq_38331606/article/details/85063724