文章目录
- 前言
- 一、领域模型持久化服务工厂
- 二、聚合创建工厂
- 1. 模型创建
- 1.1 获取域模型Class
- 1.2 新建模型
- 1.3 数据填充
 
- 2. 模型持久化
- 2.1 获取域模型对应的仓储
- 2.2 调用域模型仓储进行持久化
 
 
- 总结
前言

 本篇将解析交易信息入库,即对上送的参数,在进行校验和一些列补全后,需要进行订单的落地了。
 domainDBSaveServiceFactory.getDomainDBSaveService(context.getClientTransCode()).execute(context);
一、领域模型持久化服务工厂
领域模型持久化服务工厂定义,根据transCode+DomainDBSaveServiceImpl获取到领域模型持久化服务,获取不到则采用默认domainDBSaveService服务实现。
/**
 * @author Kkk
 * @Describe: 领域模型持久化服务工厂
 */
@Component
public class DomainDBSaveServiceFactory {
    private static final Logger logger = LoggerFactory.getLogger(DomainDBSaveServiceFactory.class);
    /**
     * 准备数据service bean 后缀
     */
    private final static String DOMAINDBSAVESERVICE_SUFF = "DomainDBSaveServiceImpl";
    /**
     * 领域模型持久化服务
     */
    @Autowired
    private Map<String, DomainDBSaveService> domainDBSaveServiceMap;
    /**
     * 默认数据持久化服务
     */
    @Resource(name = "domainDBSaveService")
    private DomainDBSaveService defaultDomainDBSaveService;
    /**
     * 获取数据持久化服务
     * @param transCode
     * @return
     */
    public DomainDBSaveService getDomainDBSaveService(String transCode) {
        String dbTransCode = TransactionManager.getTransCode(transCode);
        StringBuilder key = new StringBuilder();
        if (StringUtils.isNotBlank(dbTransCode)) {
            key.append(dbTransCode).append(DOMAINDBSAVESERVICE_SUFF);
        } else {
            key.append(transCode).append(DOMAINDBSAVESERVICE_SUFF);
        }
        DomainDBSaveService domainDBSaveService = domainDBSaveServiceMap.get(key.toString());
        if (domainDBSaveService == null) {
            LoggerUtil.info(logger, "交易({})-未获取到交易入库服务-采用默认服务", transCode);
            domainDBSaveService = defaultDomainDBSaveService;
        }
        return domainDBSaveService;
    }
}
二、聚合创建工厂
域模型工厂的bean名称为域模型类名简称+BuildFactory。
 持久化相关服务类关系如下:
 
 默认数据持久化服务:
/**
 * @author Kkk
 * @Describe: 域模型保存服务实现
 */
@Service("domainDBSaveService")
public class DomainDBSaveServiceImpl extends AbstractDomainDBSaveService {
    @Override
    public void execute(PayGwContext context) {
        super.save(context);
    }
}
/**
 * @author Kkk
 * @Describe: 域模型保存服务实现抽象层
 */
@Service
public abstract class AbstractDomainDBSaveService extends AbstractTransactionService implements DomainDBSaveService {
    private static final Logger logger = LoggerFactory.getLogger(AbstractDomainDBSaveService.class);
    /**
     * 聚合创建工厂
     */
    @Resource(name = "defaultAggregateBuildFactory")
    private DefaultAggregateBuildFactory defaultAggregateBuildFactory;
    public void save(PayGwContext context) {
        String transNo = StringUtils.valueOf(context.getMessageDescription().getData(PayGwConstant.PAYGW_TRANS_NO));
        LoggerUtil.info(logger, "交易({})-交易入库-网关流水号({})-开始", context.getClientTransCode(), transNo);
        defaultAggregateBuildFactory.save(context.getMessageDescription().getDatas());
        LoggerUtil.info(logger, "交易({})-交易入库-网关流水号({})-结束", context.getClientTransCode(), transNo);
    }
}
下面我们看默认聚合创建工厂
defaultAggregateBuildFactory.save(context.getMessageDescription().getDatas());
/**
 * @author Kkk
 * @Describe: 默认域模型工厂
 */
@Component("defaultAggregateBuildFactory")
public class DefaultAggregateBuildFactory {
    private static final Logger logger = LoggerFactory.getLogger(DefaultAggregateBuildFactory.class);
    private static final String DOMAIN_FACTORY_SUFF = "BuildFactory";//域模型构建工厂后缀
    private static final String DOMAIN_SUFF = "Domain";//domain后缀
    private static final String ENTITY_SUFF = "Entity";//entity后缀
    private static final String DOMAIN_REPOSITORY_SIMPLE_SUFF = "RepositoryImpl";//简略的域模型仓储后缀
    private static final String DOMAIN_REPOSITORY_SUFF = "DomainRepositoryImpl";//域模型仓储后缀
    
    /**
     * 交易数据入库
     * @param data
     */
    public void save(Map<String, Object> data) {
        LoggerUtil.info(logger, "交易({})-交易入库-开始", data.get(PayGwConstant.PAYGW_TRANS_CODE));
        //1、模型创建
        BusinessModel model = (BusinessModel) build(data);
        //2、模型持久化
        if (model != null) {
            store(model);
        }
        LoggerUtil.info(logger, "交易({})-交易入库-结束", data.get(PayGwConstant.PAYGW_TRANS_CODE));
    }
    /**
     * 模型构建
     * @param data
     * @return
     */
    public AggregateBase build(Map<String, Object> data) {
        //1、获取域模型Class
        String transCode = StringUtils.valueOf(data.get(PayGwConstant.PAYGW_TRANS_CODE));
        Class<? extends AggregateBase> domainClass = getDomainClassByTransCode(transCode);
        //2、新建模型
        AggregateBase domain = null;
        try {
            domain = domainClass.newInstance();
        } catch (Exception e) {
            LoggerUtil.error(logger, "交易({})-模型构建-构建模型异常", transCode);
            throw new PayGwException(SystemErrorCode.SYSTEM_ERROR, e);
        }
        //3、模型数据填充
        domain.fill(data);
        return domain;
    }
    /**
     * 根据交易码获取域模型
     * @param transCode
     * @return
     */
    public Class<? extends AggregateBase> getDomainClassByTransCode(String transCode) {
        return TransactionManager.getDomainClass(transCode);
    }
    /**
     * 模型存储
     * @param domain
     */
    public void store(AggregateBase domain) {
        //1、获取模型对应的仓储;
        BusinessModelRepository businessModelRepository = getBusinessModelRepository(domain.getClass());
        //2、调用仓储进行持久化;
        businessModelRepository.store(domain);
    }
    /**
     * @Description 模型修改
     * @Params
     * @Return
     * @Exceptions
     */
    public int modify(Map<String, Object> data) {
        //1、获取域模型
        String transCode = StringUtils.valueOf(data.get(PayGwConstant.PAYGW_TRANS_CODE));
        Class<? extends AggregateBase> domainClass = getDomainClassByTransCode(transCode);
        //2、获取模型对应的仓储
        BusinessModelRepository businessModelRepository = getBusinessModelRepository(domainClass);
        //3、调用仓储进行修改
        return businessModelRepository.modify(data);
    }
    /**
     * @Description 获取域模型仓储
     * @Params
     * @Return
     * @Exceptions
     */
    public BusinessModelRepository getBusinessModelRepository(Class domainClass) {
        String domainClassName = StringUtils.convertFirstCharToLower(domainClass.getSimpleName());
        String beanName = "";
        if (domainClassName.endsWith(DOMAIN_SUFF) || domainClassName.endsWith(ENTITY_SUFF)) {
            beanName = domainClassName + DOMAIN_REPOSITORY_SIMPLE_SUFF;
        } else {
            beanName = domainClassName + DOMAIN_REPOSITORY_SUFF;
        }
        return ApplicationContextUtil.getBean(beanName, BusinessModelRepository.class);
    }
    // ... ...
}
1. 模型创建
 //1、模型创建
 BusinessModel model = (BusinessModel) build(data);
1.1 获取域模型Class

 /**
  * 交易-模型映射
  */
 private static final Map<TransactionEnum, Class<? extends AggregateBase>> demainMapping = new HashMap<TransactionEnum, Class<? extends AggregateBase>>();
从交易-模型映射对应关系中根据transCode获取到领域模型Class。
AggregateBase 模型聚合基类定义如下:
/**
 * @author Kkk
 * @Describe: 聚合基类
 */
public abstract class AggregateBase implements Domain {
    /**
     * @Description 聚合自我检查
     * @Params
     * @Return void
     * @Exceptions
     */
    public abstract void selfCheck();
    /**
     * @Description 利用数据进行模型自我填充
     * @Params
     * @Return void
     * @Exceptions
     */
    public abstract void fill(PayGwContext context);
    /**
     * @Description 模型填充
     * @Params
     * @Return
     * @Exceptions
     */
    public abstract void fill(Map<String, Object> data);
}
1.2 新建模型
//2、新建模型
 AggregateBase domain = null;
 try {
     domain = domainClass.newInstance();
 } catch (Exception e) {
     LoggerUtil.error(logger, "交易({})-模型构建-构建模型异常", transCode);
     throw new PayGwException(SystemErrorCode.SYSTEM_ERROR, e);
 }
1.3 数据填充
 //3、数据填充
 domain.fill(data);
单笔代扣模型Deduct数据填充,即将MessageDescription中的datas属性中值映射到Deduct对象属性。
   @Override
   public void fill(Map<String, Object> data) {
       BeanUtils.populate(this, data);
   }
2. 模型持久化
 //2、模型持久化
 if (model != null) {
     store(model);
 }
2.1 获取域模型对应的仓储
根据模型名称拼装特定后缀,找到模型对应的仓储。
//1、获取模型对应的仓储;
BusinessModelRepository businessModelRepository = getBusinessModelRepository(domain.getClass());
部分模型对应的类图如下:
 
2.2 调用域模型仓储进行持久化
 //2、调用仓储进行持久化;
 businessModelRepository.store(domain);
/**
 * @author Kkk
 * @Describe: 代扣模型仓储
 */
@Repository
public class DeductDomainRepositoryImpl implements DeductDomainRepository {
    @Autowired
    private DeductTransRepository deductTransRepository;
    @Autowired
    private CardErrorManagerRepository managerRepository;
    @Override
    public void store(AggregateBase domain) {
        DeductTrans deductTrans = new DeductTrans();
        BeanUtils.copyProperties(deductTrans, (Deduct) domain);
        deductTransRepository.saveAndFlush(deductTrans);
    }
    //... ...
}
总结
本篇对交易持久化实现做了详细的介绍,大概实现思路根据上送报文的transCode从领域模型持久化服务工厂获取到领域模型持久化服务,然后进行交易数据入库工作。

![[GUET-CTF2019]encrypt 题解](https://img-blog.csdnimg.cn/1cb211f47e674b5f9a32553ad3d2578e.png)

















