【大坑】iBase4J 架构研究建议 顶

将项目跑起来,有一些个人建议,仅供作者与使用者参考~

iBase4J从技术选型来看,是没问题的,流程都一样。

我将源码debug,通读了一下,发现一些问题。

1.作者可能还没从单体应用转换为SOA服务化的思维。

文件:iBase4J-Biz-Web/src/main/resources/Spring-config.xml 中 <!-- dubbo --> <dubbo:reference id="sysProvider" interface="org.ibase4j.provider.ISysProvider" check="false" /> <dubbo:reference id="bizProvider" interface="org.ibase4j.provider.IBizProvider" check="false" />代码里dubbo的注册服务只有这两个,实际在 dubbo 里有多少个呢?只有一个。

这就导致了,dubbo无法管理这些服务,无法对服务进行限流,负载均衡,权重调节等等。

代码里,作者是怎么实现的呢?

查看源代码LoginController.java可知,通过,Parameter对象,传入service参数,method方法名,再通过,BaseProvider接口执行execute方法,找到service对应的service实现类,再找到方法,根据Parameter对象传入的Map或Bean,并去执行此方法。

``` provider.execute(new Parameter("sysUserService", "update").setModel(sysUser)); ```

严重性:极高 缺点:      客户端必须要知道接口名。      客户端必须要知道有哪些参数。      dubbo无法很好的进行服务治理,负载均衡等等。

建议:     1.将所有服务化暴露给duboo.     2.服务化可以在ctrl层直接调用.     3.封装api层,model层给客户端。 2.在service中,Map与Bean混用。

如SysUserService类中: ```     @Cacheable     public Long queryUserIdByThirdParty(ThirdPartyUser param) {         return thirdpartyMapper.queryUserIdByThirdParty(param.getProvider(), param.getOpenid());     } ``` ``` public Page<SysUser> query(Map<String, Object> params) {         Map<String, String> userTypeMap = sysDicService.queryDicByType("USERTYPE");         Page<SysUser> pageInfo = super.query(params);         for (SysUser userBean : pageInfo.getRecords()) {             if (userBean.getUserType() != null) {                 userBean.setUserTypeText(userTypeMap.get(userBean.getUserType().toString()));             }             if (userBean.getDeptId() != null) {                 SysDept sysDept = sysDeptService.queryById(userBean.getDeptId());                 if (sysDept != null) {                     userBean.setDeptName(sysDept.getDeptName());                 }             }             List<String> permissions = sysAuthorizeService.queryUserPermission(userBean.getId());             for (String permission : permissions) {                 if (StringUtils.isBlank(userBean.getPermission())) {                     userBean.setPermission(permission);                 } else {                     userBean.setPermission(userBean.getPermission() + ";" + permission);                 }             }         }         return pageInfo;     } ``` 根据阿里巴巴 Java 开发手册1.1.1 来看,不建议这样做,2个以上的参数,最好封装成查询Bean。

3.对于Redis缓存使用有点原始,数据字典处理有点原始。

如SysUserService类中,对于字典的文本读取转换: ``` public Page<SysUser> query(Map<String, Object> params) {         Map<String, String> userTypeMap = sysDicService.queryDicByType("USERTYPE");         Page<SysUser> pageInfo = super.query(params);         for (SysUser userBean : pageInfo.getRecords()) {             if (userBean.getUserType() != null) {                 userBean.setUserTypeText(userTypeMap.get(userBean.getUserType().toString()));             }             if (userBean.getDeptId() != null) {                 SysDept sysDept = sysDeptService.queryById(userBean.getDeptId());                 if (sysDept != null) {                     userBean.setDeptName(sysDept.getDeptName());                 }             }             List<String> permissions = sysAuthorizeService.queryUserPermission(userBean.getId());             for (String permission : permissions) {                 if (StringUtils.isBlank(userBean.getPermission())) {                     userBean.setPermission(permission);                 } else {                     userBean.setPermission(userBean.getPermission() + ";" + permission);                 }             }         }         return pageInfo;     } ```

如LoginController类中,对于缓存: ``` String password = (String)CacheUtil.getCache().get("LOGIN_" + user.getAccount());         if (StringUtils.isNotBlank(password)) {             if (user.getPassword().equals(password)) {                 WebUtil.saveCurrentUser(request, user.getAccount());                 success = true;             }         } ``` 如BaseService类中,对于缓存: ``` @Transactional     @SuppressWarnings("unchecked")     public T queryById(Long id) {         String key = getCacheKey(id);         T record = (T) CacheUtil.getCache().get(key);         if (record == null) {             String lockKey = getLockKey(id);             if (CacheUtil.getLock(lockKey)) {                 try {                     record = mapper.selectById(id);                     CacheUtil.getCache().set(key, record);                 } finally {                     CacheUtil.unlock(lockKey);                 }             } else {                 logger.debug(getClass().getSimpleName() + ":" + id + " retry queryById.");                 sleep(20);                 return queryById(id);             }         }         return record;     } ```

4.手动事务控制与Service的异常处理 如BaseService中: ``` 大量出现 @Transactional ```

```  @Transactional     public void delete(Long id) {         try {             mapper.deleteById(id);             CacheUtil.getCache().del(getCacheKey(id));         } catch (Exception e) {             throw new RuntimeException(e.getMessage(), e);         }     } ``` ```     @Transactional     public void del(Long id, Long userId) {         try {             T record = this.queryById(id);             record.setEnable(0);             record.setUpdateTime(new Date());             record.setUpdateBy(userId);             mapper.updateById(record);             CacheUtil.getCache().set(getCacheKey(id), record);         } catch (Exception e) {             throw new RuntimeException(e.getMessage(), e);         }     } ```

5.一不小心就被坑的机制

如BaseService中: ```   @Transactional     public T update(T record) {         try {             record.setUpdateTime(new Date());             if (record.getId() == null) {                 record.setCreateTime(new Date());                 mapper.insert(record);             } else {                 T org = this.queryById(record.getId());                 String lockKey = getLockKey(record.getId());                 if (CacheUtil.getLock(lockKey)) {                     try {                         T update = InstanceUtil.getDiff(org, record);                         update.setId(record.getId());                         mapper.updateById(update);                         record = mapper.selectById(record.getId());                         CacheUtil.getCache().set(getCacheKey(record.getId()), record);                     } finally {                         CacheUtil.unlock(lockKey);                     }                 } else {                     sleep(20);                     return update(record);                 }             }         } catch (DuplicateKeyException e) {             String msg = ExceptionUtil.getStackTraceAsString(e);             logger.error(Constants.Exception_Head + msg, e);             throw new RuntimeException("已经存在相同的配置.");         } catch (Exception e) {             String msg = ExceptionUtil.getStackTraceAsString(e);             logger.error(Constants.Exception_Head + msg, e);             throw new RuntimeException(msg);         }         return record;     } ``` 高并发情况下的锁与无限循环

其他的我后面再补充

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券