当前位置: 首页 > news >正文

本地化部署后定制解决方案

本人做过很多互联网项目,也做过很多企事业单位的项目,比如监管系统,临床试验系统等,这些系统主要是看守所,医院在用,这些单位对网络安全比较重视,都需要本地化部署,因为每个单位对系统的需求不同,所以还需要定制开发,如何管理base版本和定制化版本,是个大问题,现提供几种思路。

1.通过分支区分版本

如果不需要定制化开发,直接部署base版本即可,如果需要定制化开发,则从base版本中拉一个分支,在这个分支中开发,但是后续升级会很麻烦,所以这种方案是不考虑升级的,优点是实现简单,缺点是无法升级,只有特定情况下才会使用这种方案。

2.通过新建目录的方式打补丁

比如我要定制化一个ny的版本,就新建一个ny的包,里面也包含controller,service,mapper等,跟主包的目录层级一样,

在配置环境中加一个配置,用来确定当前环境,比如基准版本用base,ny版本就用ny

system.config.context=ny

基准版本要做差异化的部分加上条件渲染,比如ny版本用户管理的功能有差异

这样写后这两个类只会在base环境下才会生成bean

然后我们生成ny下的controller和service

controller代码:

要继承UserController,这样原有的功能都会继承,我们只需要写差异化代码就行了,比如原来有listPage接口,但是不符合ny版本要求,需要改造,直接覆盖这个方法就行了,又比如要加新功能,则直接加新接口就行了,这样还有个好处是基准版本加了新功能,ny版本可以直接继承,这样升级起来就很方便了

@RestController
@RequestMapping("/admin/user")
@Api(tags = "ny用户管理")
@ConditionalOnProperty(prefix = "system.config.", name="context", havingValue = "ny")
public class NyUserController extends UserController {@Autowiredprivate NyUserService nyUserService;@ApiOperation(value = "ny分页查询用户,支持动态拼参,排序")@ApiImplicitParams({@ApiImplicitParam(name = "page", value = "当前页码", dataType = "int", paramType = "query", required = false),@ApiImplicitParam(name = "rows", value = "每页记录数", dataType = "int", paramType = "query", required = false),@ApiImplicitParam(name = "orderItem", value = "排序字段", dataType = "String", paramType = "query", required = false),@ApiImplicitParam(name = "sortDir", value = "排序方式", dataType = "String", paramType = "query", required = false)})@GetMapping("listPage")public Result<UserDto> listPage(@RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "20") int rows, String orderItem, String sortDir, HttpServletRequest request) {System.out.println("我修改了base接口");Map<String, Object> searchParam = Servlets.getParametersStartingWith(request, PARAM_PREFIX);IPage<UserDto> iPage = nyUserService.listPage(searchParam, orderItem, sortDir, page, rows);return resultOk(iPage);}@ApiOperation(value = "查询用户总数")@GetMapping("getUserCount")public Result getUserCount() {int count = nyUserService.getUserCount();return resultOk(count);}
}

service代码:

service层也是同理,继承UserService

public interface NyUserService extends UserService {int getUserCount();
}

在实现类中,我们新建了一个NyUserMapper,这样有差异化的代码都可以写在这个mapper里面

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
@ConditionalOnProperty(prefix = "system.config.", name="context", havingValue = "ny")
public class NyUserServiceImpl extends UserServiceImpl implements NyUserService {@Autowiredprivate NyUserMapper nyUserMapper;@Overridepublic IPage<UserDto> listPage(Map<String, Object> searchParam, String orderItem, String sortDir, int page, int rows) {System.out.println("我修改了service");return super.listPage(searchParam, orderItem, sortDir, page, rows);}@Overridepublic int getUserCount() {return nyUserMapper.getUserCount();}
}

mapper代码:

public interface NyUserMapper extends BaseMapper<User> {int getUserCount();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itrial.itrialpay.ny.mapper.NyUserMapper"><select id="getUserCount" resultType="java.lang.Integer">select count(*) from user</select>
</mapper>

扫描包方面的改动,我用的是mybatis-plus,要扫描到子目录的mapper文件中间需要加**

#mybatis-plus配置
mybatis-plus.mapper-locations=classpath*:mapper/**/*.xml

同理,启动类上面包扫描也要加**

swagger改造,我试了下swagger好像不支持**,所以用了basePackage的or,支持多个包,当然也可以直接指定com.itrial.itrialpay这样下面所有包都能扫到

    @Beanpublic Docket adminApi() {List<ResponseMessage> responseMessageList = new ArrayList();responseMessageList.add((new ResponseMessageBuilder()).code(200).message("请求成功").build());return new Docket(DocumentationType.SWAGGER_2).directModelSubstitute(LocalDateTime.class, Date.class).directModelSubstitute(LocalDate.class, Date.class).directModelSubstitute(LocalTime.class, Date.class).groupName("管理端接口").globalResponseMessage(RequestMethod.GET, responseMessageList).globalResponseMessage(RequestMethod.POST, responseMessageList).globalResponseMessage(RequestMethod.PUT, responseMessageList).globalResponseMessage(RequestMethod.DELETE, responseMessageList).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.itrial.itrialpay.controller.admin").or(RequestHandlerSelectors.basePackage("com.itrial.itrialpay." + systemConfig.getContext() + ".controller.admin"))).build().securitySchemes(securitySchemes()).securityContexts(securityContexts());}

http://www.dtcms.com/a/569631.html

相关文章:

  • Java中的WebSocket与实时通信!
  • SQL server创建数据表
  • MacOS-Terminal直接command解压缩文件文件夹
  • GIM 模型转 GLB 模型:从格式适配到前端渲染的完整方案
  • 什么是网站平台开发wordpress链接优化
  • 软件测试——自动化测试概念
  • 大模型-详解 Vision Transformer (ViT)
  • 建站公司互橙知乎郑州seo哪家专业
  • 09-ubuntu20.04 执行 apt update时报错,是因为官网已停止维护不再更新的缘故吗?
  • 南通做网站找谁求网站懂的说下开车
  • ps做网站宽度重庆公司团建推荐
  • uniapp中的uni_modules分包
  • 算法笔记 09
  • 【VLAs篇】08:以实时速度运行VLA
  • 广西桂林建设局网站建立网站需要多少钱 索 圈湖南岚鸿
  • 买完服务器怎么做网站网页编辑软件绿色
  • 从奠基到前沿:CIFAR-10 数据集如何驱动计算机视觉研发进化
  • 计算机网络第六章学习
  • 华为A800I A2 arm64架构鲲鹏920cpu的ubuntu22.04 tls配置直通的grub配置
  • 耐热型发光颜料:高温环境下的功能材料新星
  • 简单易做的的网站做网站一定要注册域名吗
  • 正态分布概率:1σ、2σ、3σ、4σ深度解读
  • 红帽Linux-调优系统性能
  • python找到文件夹A中但是不在文件夹B中的文件
  • 做企业网站要怎么设计方案机关单位网站安全建设
  • 网站建设乙方义务wordpress 模板 淘宝客
  • 归并排序解读(基于java实现)
  • 从0开始学算法——第一天(如何高效学习算法)
  • 相似度计算算法系统性总结
  • 大型网站建设用什么系统好佛山网站设计哪里好