上一篇中介绍了开发平台存在的问题,解决思路就是模块化重构,并做了大概的规划,再来回顾下。
popsoft-plaform:聚合项目,用于管理开发平台各模块的源码。
popsoft-common:公用基础,包括工具类
popsoft-framework:平台框架
popsoft-system:系统管理模块,包括组织机构、人员、权限、日志
popsoft-generator:代码生成器,基于库表和模板技术快速生成entity、vo、dao、service、controller、ui的各层代码
popsoft-boot-starter:平台启动项目,整合平台基础功能,类似于spring-boot-starter,业务系统引入该包进行依赖
popsoft-boot:启动项目,可视为业务系统模拟,用于平台自身功能开发与调试
popsoft-support:业务支撑,提供单据流水号、消息通知、内容模板、门户等功能
通常是中间件的集成,具体的业务系统按需依赖
popsoft-boot-starter-mail:邮件
popsoft-boot-starter-oss: 对象存储
popsoft-boot-starter-scheduler:任务调度
……
在实现过程中,进行了比较多的思考,在重构过程中进行模块的拆分与合并,包和类的转移、配置文件的调整,特别是梳理模块间的依赖关系,最终输出版本与之前的规划并不完全一致。
先把最后输出的模块架构图成果放出来,然后把重构过程中思考的一些问题点放在其后。
首先分成两部分,一部分是平台内核模块,命名规则是popsoft+模块功能名称;另一部分是能力扩展模块,命名规则是popsoft-boot-starter+模块功能名称。
popsoft-common作为公用基础,主要包括工具类、公用注解、公共父类、公共常量、公共枚举值,与前端UI交互定义的vo类,该模块为最基础的模块,无前置依赖。
popsoft-system是平台最核心的模块,主要包括组织机构、人员、角色、权限、日志、系统参数这些实体和服务的实现,需要注意的是,权限控制、日志记录,并不是在该模块实现,而是在popsoft-framework平台框架中实现,该模块依赖于popsoft-common。
popsoft-framework是平台框架,负责身份认证、权限控制、全局配置、数据分页、日志处理、自动填充(创建人、创建时间、修改人、修改时间),因为身份认证、权限控制等功能,不可避免需要使用处于popsoft-system模块中的人员、角色等实体和服务,因此依赖于popsoft-system。
popsoft-support是一个业务支撑模块,基于技术组件进行功能设计与封装,实现一些通用的功能设计,更方便业务逻辑的实现,提供附件管理、内容模板(用于短信、邮件、消息)、通讯组、单据流水号、门户等功能。这些支撑模块同样需要位于popsoft-system模块中的人员、组织机构等实体和服务,因此依赖于popsoft-system。
popsoft-boot-starter:平台启动项目,整合平台基础功能,类似于spring-boot-starter,业务系统引入该包进行依赖。该模块自身没有实体与服务,而是汇总整合,把popsoft-framework和popsoft-support引用进来,同时进行配置。配置分两方面,一方面是做一个配置类,加一些注解(如:@EnableRetry、@ServletComponentScan、@EnableTransactionManagement),使用开发平台实现的业务系统,就不需要在启动类上重复添加这些注解;另一方面,是位于yml配置文件中的配置信息,也分为两部分,一部分是三方组件自身的,如数据源、连接池、redis、quartz、logback,另一方面是自定义的系统参数,如用户默认密码、导出excel数据的批次最大行数量。
popsoft-boot-starter-demo:示例项目,实际是模拟业务系统如何使用开发平台,用于平台自身功能开发与调试。
右侧四个模块,比较好理解,通常是对第三方组件的封装与整合,依赖于公共基础模块popsoft-common,这些模块可以不断扩展的,业务系统按需引入即可,这样就实现了核心模块必选、扩展模块可选的目的。
popsoft-boot-starter-mail:邮件
popsoft-boot-starter-oss: 对象存储
popsoft-boot-starter-scheduler:任务调度
popsoft-boot-starter-notification:消息通知
对于扩展模块,平台的核心模块实际也可能会用到,例如popsoft-support中的附件功能,就会用到popsoft-boot-starter-oss;popsoft-system中的自动解锁用户功能,就会用到popsoft-boot-starter-scheduler。
为了主体逻辑清晰,以上依赖关系没有在图中绘制出来。
这是一个比较纠结的点。
原先的想法,公共基础模块common之上,就应该是平台框架framework,由框架来实现身份认证、权限控制等,然后才是基于框架产生的system、support等模块。
实际遇到的问题,要做身份认证,肯定会用到用户服务,而用户服务是位于system模块下,也就是依赖关系倒置了。
尝试过一些方法,例如,将用户服务的接口UserService,下沉到common模块,问题是能解决,但是一定程度上破坏了system的内聚性。而且,涉及到的不仅仅是用户服务,在framework模块中,用户登录成功后,我们需要同样位于system模块下的组织机构服务OrganizationService,查下这个用户的所属的部门、公司、集团等信息,缓存到用户对象中。
转变下思路,将system模块,作为common模块之上的首个基础模块,从架构上反而更合理。
两个模块都依赖于system,职责不同,初期规划是一个单向依赖,实际发现二者并不存在谁依赖谁的问题,并列反而最合适。
承接上个问题,客观上需要一个模块,来把平台核心模块都给组装起来,对外提供一个包,就像使用SpringBoot一样,业务系统要使用平台,只要引入spring-boot-starter这个项目即可,需要在这个项目中做一些全局的配置工作。
如果缺少这个模块,那么业务系统在使用的时候,必须同时引入framework和support两个包,这样就很别扭。
这个模块实际作用有两个,一是平台自身功能开发与调试,需要一个测试启动点,因为平台最终是打成不可独立运行的jar包,提供给业务系统去依赖,没有这个模块,总不能拿一个具体业务系统作为启动项目吧;另一方面,这个模块也真实模拟业务系统如何使用开发平台,更容易发现平台自身存在的问题。