1. 程式人生 > >SpringBank 開發日誌 重新設計Action調用Service的參數傳遞 使用泛型解決類型轉換問題

SpringBank 開發日誌 重新設計Action調用Service的參數傳遞 使用泛型解決類型轉換問題

from eth 開始 request 攔截 反射 list 日期 check

之前想的比較簡單,請求到達controller的時候,傳給action的參數沒有經過任何封裝,就是一個Map。然後action再調用service的時候,傳遞的參數也是map

@Controller
public class DepositController extends BaseController{
    @TransactionMapping(transaction = "Deposit")
    public Map Deposit(Map request) {
        Map map = callService(ServiceDict.DepositService, request);
        return map;
    }
}

但是當我在做存款交易的時候,我隱隱約感覺這樣很有問題,因為再action裏面完全無法看出來付款人收款人金額等等重要信息,雖然實際上這些信息在調用Service之前會經過一系列攔截器,但是當到達service裏面的時候,參數又要從map裏面get一遍,感覺很不舒服,就像沒有經過校驗的原始數據一樣。

所以我想確實action調用service的時候,應該將參數封裝到專門的請求參數類裏面。

// 日切
    @TransactionMapping(transaction = "NextAccountingDate")
    public Map nextAccountingDate(Map request) {
        Map map 
= callService(ServiceDict.NextAccountingDateService,new NextAccountingDateRequest()); return map; }

以日切交易為例,我搞了一個NextAccountingDateRequest,封裝該Service需要的參數(實際上這個交易沒有任何參數,只是舉例)

public abstract class Service {
    
    private List<Interceptor> interceptorList;
    
    @SuppressWarnings(
"rawtypes") public abstract Map execute(Object request); public List<Interceptor> getInterceptorList() { return interceptorList; } public void setInterceptorList(List<Interceptor> interceptorList) { this.interceptorList = interceptorList; } }

但是我是反射的方式調用Service,所有的service都繼承了上面的這個抽象類Service,所以execute方法的參數就是需要考慮的問題。一開始如上圖所示,我使用Object來接收,可是Service裏面呢

public class NextAccountingDateService extends Service<NextAccountingDateRequest>{

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Map execute(NextAccountingDateRequest request) {
        // TODO Auto-generated method stub
        Map result = new HashMap();
        
        //先查出當前賬務日期
        String pdat = DaoUtil.getMapper(SysparamMapper.class).selectByPrimaryKey(CommonDict.PDAT).getValue();
        Date currentDate = DateUtil.getDateFromStr(pdat);
        
        //計算下一日期
        Date nextDate = DateUtil.getNextDate(currentDate);
        
        //record
        Sysparam record = new Sysparam();
        record.setValue(DateUtil.getDateDashFormat(nextDate));
        
        //example
        SysparamExample example = new SysparamExample();
        example.createCriteria().andKeyEqualTo(CommonDict.PDAT);
        
        //do update
        DaoUtil.getMapper(SysparamMapper.class).updateByExampleSelective(record, example);
        
        //query again
        pdat = DaoUtil.getMapper(SysparamMapper.class).selectByPrimaryKey(CommonDict.PDAT).getValue();
        
        result.put("pdat", pdat);
        return result;
    }
}

這裏肯定就編譯不過了,需要強轉。所以為了解決這個問題,最終使用了泛型

public abstract class Service<T> {
    
    private List<Interceptor> interceptorList;
    
    @SuppressWarnings("rawtypes")
    public abstract Map execute(T request);
    
    public List<Interceptor> getInterceptorList() {
        return interceptorList;
    }
    public void setInterceptorList(List<Interceptor> interceptorList) {
        this.interceptorList = interceptorList;
    }
}

使用泛型過後的抽象Service類就是上面這樣。

這樣一來就避免立刻了在代碼中出現強制轉換的多余的代碼,當然編譯器可能也是強轉的。但至少自己寫的代碼看起來整潔多了

SpringBank 開發日誌 重新設計Action調用Service的參數傳遞 使用泛型解決類型轉換問題