服务介绍
技术栈

架构图

服务介绍
认证服务: lamp-oauth
主要包括:
- 登录 相关接口
- 获取用户信息、权限、菜单等 接口
- 常用数据接口(如前端获取的字典、枚举接口)
系统服务: lamp-system
主要包括:
- 开发运营系统的接口基本都在系统服务
- 应用管理:应用维护、给租户授权应用、给应用配置全局资源
- 平台级系统管理:维护字典、参数、客户端等
- 租户管理、给租户创建独立数据源(数据源模式)、租户管理员维护、 租户表结构初始化、租户表数据初始化 等功能。
基础服务: lamp-base
主要包括:
- 基础平台的接口基本都在base服务
- 基础功能 组织机构管理、岗位管理、租户下的员工管理、租户级系统设置、角色权限分配等功能。
- 站内信(通知、公告、待办、预警)、短信功能、邮件功能(尚未实现) 等。 支持多种第三方短信、多种第三方邮件。
- 文件存储、文件下载、文件回显等功能,支持多种第三方OSS存储。
代码生成服务: lamp-generator
- 【开发运营系统】-【开发工具】下代码生成相关接口
- 支持MySQL、Oracle、SQL Server
- 能生成lamp-cloud的服务和lamp-boot的模块
- 能生成lamp-cloud和lamp-boot的java代码
- 能生成lamp-web-pro的前端代码
网关服务: lamp-gateway
主要包括 token解析、接口(uri)权限拦截、黑白名单、限流等功能。
监控: lamp-monitor
SpringBootAdmin 监控功能
概念声明
- 层
- facade层: 包含lamp-xxx-api、lamp-xxx-boot-impl、lamp-xxx-cloud-impl 等模块
- lamp-xxx-api:定义接口,一般是跨服务或跨模块调用的接口
- lamp-xxx-boot-impl:采用单体版方式,实现api层中的接口
- lamp-xxx-cloud-impl:采用微服务版方式,实现api层中的接口
- 业务层:包含lamp-base-biz、lamp-system-biz、lamp-oauth-biz等模块
- 控制层:包含lamp-base-controller、lamp-system-controller、lamp-oauth-controller等模块
- 实体层:包含lamp-base-entity、lamp-system-entity、lamp-oauth-entity等模块
- 启动层:包含lamp-base-server、lamp-system-server、lamp-oauth-server、lamp-boot-server等模块
- facade层: 包含lamp-xxx-api、lamp-xxx-boot-impl、lamp-xxx-cloud-impl 等模块
- 模块
- lamp-util 项目下的每个包. 如 lamp-core、 lamp-cloud-starter
- lamp-datasource-max 和 lamp-column-max 项目下的每个包. 如lamp-base、lamp-common等
- 服务
- 认证服务:lamp-oauth下的所有模块组成权限服务
- 系统服务:lamp-system下的所有模块组成租户服务
- 基础服务:lamp-base下的所有模块组成权限服务
- 网关服务:lamp-gateway下的所有模块组成网关服务
- 代码生成服务:lamp-generator下的所有模块组成代码生成服务
- 监控服务:lamp-monitor
- lamp-public 目录下存放 业务服务公共模块和收费的插件 :
- lamp-common 模块用于存放跟大多数服务有关的常量类和工具类等
- lamp-data-scope-sdk:数据权限插件
- lamp-database-mode:租户模式实现插件。如DATASOURCE模式、COLUMN模式、NONE模式的实现类
- lamp-file-sdk:附件sdk,用于业务服务保存和查询业务附件信息
- lamp-model:公共的model对象
- lamp-login-user-facade:用户信息注入器
- lamp-tenant-datasource-init (datasource模式专属) : DATASOURCE模式的初始化数据源模块,用于业务服务启动时,初始化租户数据源
总结: 一个服务可以包含多个模块,一个模块可以包含多个层。
疑问🤔️
已经是微服务项目了, 为什么还要将项目按模块拆封得如此细?
- 受到原来项目的“影响”, 已经习惯了将一个大项目按照功能拆封成多个模块的习惯
- 按照大功能将代码物理拆分成多个模块后, 强制按照server -> controller -> biz -> entity 层的依赖关系来开发功能
- 可以让项目结构更加清晰, 是典型的低耦合、高内聚体现;
- 可以避免开发水平参差不齐的团队,胡乱添加依赖, 胡乱注入Bean. (只允许: Controller 调用 Service, Service调用Mapper)
- 当某个项目不需要某个功能时(如没有站内信、没有短信发送、没有操作日志等), 按模块拆分的短信和站内信可以很轻松的在消息服务排除或者删除这2个功能。
- 方便一个项目同时支持单体模式或微服务模式!
服务拆分模块建议
原则上推荐一个服务最好包含5个模块(api模块、entity模块、biz模块、controller层、server层), 但任何事情都不是绝对的,具体怎么分模块可以根据业务自身情况来定. 如: 消息服务希望将站内消息、短信、邮件等相关等逻辑集成到消息服务, 这几个功能既有独立性, 做得更细一些,甚至可以将站内消息、短信、邮件等功能独立成单独的服务, 但这务必会增加系统部署开销, 所以综合考虑, 将站内消息、短信、邮件等功能按模块开发,然后组合成一个服务, 即降低了部署等成本,也将每个功能独立出来,方便日后独立成单独的服务和禁用某些功能.
依赖关系

facade层
《灯灯》为了实现1个项目,同时支持单体版和微服务版启动,引入了facade层。facade层用于跨服务/跨模块之间的接口调用,facade层包含3个子模块,分别是api、boot-impl、cloud-impl。
- lamp-xxx-api:定义接口,一般是跨服务或跨模块调用的接口
- lamp-xxx-boot-impl:采用单体版方式,实现api层中的接口
- lamp-xxx-cloud-impl:采用微服务版方式,实现api层中的接口
举个栗子:
lamp-oauth服务的CaptchaServiceImpl类,调用lamp-base服务的短信发送接口。
在lamp-oauth-biz/pom.xml 中添加依赖
<dependency> <groupId>top.tangyh.lamp</groupId> <artifactId>lamp-base-api</artifactId> <version>${lamp-project.version}</version> </dependency>
对于微服务模式,在lamp-oauth-server/pom.xml 中添加依赖
<!-- 基础服务相关接口 - 微服务版实现类 --> <dependency> <groupId>top.tangyh.lamp</groupId> <artifactId>lamp-base-cloud-impl</artifactId> <version>${lamp-project.version}</version> </dependency>
对于单体模式,在lamp-boot-server/pom.xml中添加依赖
<!-- 基础服务相关接口 - 单体版实现类 --> <dependency> <groupId>top.tangyh.lamp</groupId> <artifactId>lamp-base-boot-impl</artifactId> <version>${lamp-project.version}</version> </dependency>
具体的实现代码
public class CaptchaServiceImpl implements CaptchaService {
private final MsgFacade msgFacade;
public R<Boolean> sendSmsCode(String mobile, String templateCode) {
// 其他代码已忽略...
// 调用 lamp-base服务的短信发送接口
ExtendMsgSendVO msgSendVO = ExtendMsgSendVO.builder().code(templateCode).build();
msgSendVO.addParam("code", code);
msgSendVO.addRecipient(mobile);
ContextUtil.setBuiltTenantId();
return R.success(msgFacade.sendByTemplate(msgSendVO));
}
}
public interface MsgFacade {
/**
* 根据模板发送消息
*
* @param data 发送内容
* @return
*/
Boolean sendByTemplate(ExtendMsgSendVO data);
}
@Service
@RequiredArgsConstructor
public class MsgFacadeImpl implements MsgFacade {
private final MsgBiz msgBiz;
@Override
public Boolean sendByTemplate(ExtendMsgSendVO data) {
// 单体版具体的 实现方案
return msgBiz.sendByTemplate(data, null);
}
}
@Service
public class MsgFacadeImpl implements MsgFacade {
@Lazy
@Autowired
private MsgApi msgApi;
@Override
public Boolean sendByTemplate(ExtendMsgSendVO data) {
// 微服务版具体的 实现方案
R<Boolean> result = msgApi.sendByTemplate(data);
return result.getIsSuccess() && result.getData();
}
}
注意
请勿将lamp-base-cloud-impl和lamp-base-boot-impl同时加入一个服务。
严格遵守:微服务模式,使用lamp-base-cloud-impl;单体模式,使用lamp-base-boot-impl
业务层
主要存放Service接口及实现,Redis操作类、Mapper接口以及Xml(resources目录下)。 约定如下:
AService 能注入BService,但禁止直接或间接循环注入。如AService -> BService ,BService->AService 在Service 层封装 业务逻辑, 操作缓存接口、Mapper接口的操作
实体层
存放实体po、文件传输对象DTO(本项目忽略VO)、枚举类型等,不涉及逻辑的一些类。
控制层
主要存放一些服务的 Contrller 接口, 用于对外访问。 约定如下:
Controller 不能互相注入调用(我不说,真有人这么干!) Controller 只能调用Service,禁止调用Mapper(Dao) Controller 主要负责参数验证、转换等操作,尽量别写业务代码
启动层说明
主要存放一些服务所需的启动类、配置类、配置文件、消息队列消费方监听入口等
每个层的依赖关系
每个服务一般情况下都包含5个层: server、controller、biz、entity、api (特殊情况可以删减一些),他们的依赖依赖关系为: server -> controller -> biz -> entity
,api层独立,用于其他服务依赖。
项目模块依赖图

调用流程

❗️❗️❗️若评论区无法显示,请使用"手机热点"或"科学上网"。