1. 程式人生 > >業務程式碼:基於spring的銀行支付介面模型實現

業務程式碼:基於spring的銀行支付介面模型實現

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";
    }
    
}