springboot使用自定義註解和反射實現一個簡單的支付

 

 

優勢:java

未使用if else,就算之後增長支付類型,也不用改動以前代碼git

只須要新寫一個支付類,給添加自定義註解@Paygithub

 

首先:web

定義自定義註解 Payspring

定義 CMBPay ICBCPay 兩種支付 根據註解中的value 標識是哪一種支付(1爲CMBPay  2爲ICBCPay)編程

兩種支付都需繼承InitNewService.java 避免注入對象報錯ide

 

package com.huarui.inter;

import java.math.BigDecimal;

/**
 * 支付需實現該接口
 * 接口編程:
 */
public interface Strategy {

    /**
     * 計算支付金額 經過渠道id和商品id 進行價格計算
     * @param channelId
     * @param goodsId
     * @return
     */
    BigDecimal calRecharge(Integer channelId,Integer goodsId);

} 

 

package com.huarui.pay;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE) //註解定義到類上
@Retention(RetentionPolicy.RUNTIME) //生命週期
public @interface Pay {

    int value();

} 
@Pay(2)
public class ICBCPay extends InitNewService implements Strategy {
    
    @Override
    public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
        //經過渠道id查詢優惠折扣

        //經過商品id查詢商品價格

        //返回商品最終價格
        return new BigDecimal(100);
    }
}
ICBCPay.java
package com.huarui.pay;

import com.huarui.inter.Strategy;
import com.huarui.util.CommonUtil;
import com.huarui.util.InitNewService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;

@Pay(1)
public class CMBPay extends InitNewService implements Strategy {

    @Autowired
    private CommonUtil commonUtil;

    @Override
    public BigDecimal calRecharge(Integer channelId, Integer goodsId) {
        //經過渠道id查詢優惠折扣

        //經過商品id查詢商品價格

        System.out.println(commonUtil.injectStr());

        //返回商品最終價格
        return new BigDecimal(100);
    }
}
CMBPay.java

 

package com.huarui.factory;

import com.huarui.inter.Strategy;
import com.huarui.pay.Pay;
import org.reflections.Reflections;

import java.util.HashMap;
import java.util.Set;

/**
 * 【工廠類】
 * 經過指定掃碼路徑讀取帶有自定義註解Pay的類
 * <br>並將全類名保存至map中,格式爲["pay的value":"類的全類名"]
 * <br> 定義了creator方法,傳入支付類型 返回 指定支付對象
 */
public class StrategyFactory {


    private static StrategyFactory factory = new StrategyFactory();

    /**
     * 單例
     * @return
     */
    public static StrategyFactory getInstance(){
        return factory;
    }

    public static HashMap<Integer,String> sourceMap = new HashMap<>();

    static {

        //反射工具包,指明掃描路徑
        Reflections reflections = new Reflections("com.huarui.pay");
        //獲取帶咱們pay註解的類
        Set<Class<?>> classSet =  reflections.getTypesAnnotatedWith(Pay.class);
        //根據註解的值,將全類名放到map中
        for (Class clazz : classSet){
            Pay pay = (Pay) clazz.getAnnotation(Pay.class);
            sourceMap.put(pay.value(),clazz.getCanonicalName());
        }

    }

    public Strategy creator(int type) throws Exception {
        //取得全類名
        String className = sourceMap.get(type);
        //取得類對象
        Class  clazz= Class.forName(className);
        //反射建立對象
        return (Strategy) clazz.newInstance();
    }

} 
package com.huarui.inter;

import com.huarui.factory.StrategyFactory;

import java.math.BigDecimal;

public class Context {

    /**
     *
     * @param channelId 支付類型id
     * @param goodsId   商品id
     * @return
     * @throws Exception
     */
    public BigDecimal calRecharge(Integer channelId,Integer goodsId) throws Exception {
        Strategy strategy = StrategyFactory.getInstance().creator(channelId);
        return strategy.calRecharge(channelId,goodsId);
    }
} 

 

junit測試類工具

 

 

package com.huarui;

import com.huarui.inter.Context;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.math.BigDecimal;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SbCodeApplicationTests {

    @Test
    public void contextLoads() throws Exception {

        Context context = new Context();
        BigDecimal bigDecimal = context.calRecharge(1,500);
        System.out.println(bigDecimal);

    }

}

 

項目結構:測試

 

源碼地址: https://github.com/youxiu326/sb_codeui

相關文章
相關標籤/搜索