zoukankan      html  css  js  c++  java
  • SpringBank 开发日志 重新设计Action调用Service的参数传递 使用泛型解决类型转换问题

    之前想的比较简单,请求到达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类就是上面这样。

    这样一来就避免立刻了在代码中出现强制转换的多余的代码,当然编译器可能也是强转的。但至少自己写的代码看起来整洁多了

  • 相关阅读:
    Java代理模式
    PHP7.3.0+弃用FILTER_FLAG_SCHEME_REQUIRED的解决办法
    《PHP7底层设计与源码实现》学习笔记1——PHP7的新特性和源码结构
    《MySQL实战45讲》学习笔记2——MySQL的日志系统
    PHP反射学习总结
    依赖注入模式中,为什么用对象而不是用数组传递?
    记MySQL的一次查询经历
    数据结构与算法之PHP递归函数
    PHP的json_encode()函数与JSON对象
    Linux系统如何查看版本信息
  • 原文地址:https://www.cnblogs.com/heben/p/7264645.html
Copyright © 2011-2022 走看看