# backend_liangang_mes2.0
**Repository Path**: yinginx/backend_liangang_mes2.0
## Basic Information
- **Project Name**: backend_liangang_mes2.0
- **Description**: MES系统后端接口工程
- **Primary Language**: Java
- **License**: GPL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2024-08-30
- **Last Updated**: 2025-10-10
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
欢迎使用上海应星 Java 后端脚手架 1.0
(idea 里需要设置 maven3.8,settings.xml 需要更改为本地 localRepository 路径,并替换 repository com 包)
1、开始使用
1.1 项目创建
使用 IntelliJ IDEA 创建项目(按新版 UI 编写,旧 UI 自行尝试或改用命令行方式)
Step 1:File -> New -> Project -> Maven archetype。
Step 2:Archetype -> Add。
Step 3:填写 GroupId=com.yinginx,ArtifactId=archetype-archetype,Version:1.0.0-SNAPSHOT。
Step 4:选择 com.yinginx.archetype-archetype,点击 Next。
Step 5:输入项目 GroupId,ArtifactId,Version、Package 即可。
无论使用的是哪个创建方式,GroupId 均需要以 com.yinginx.开头!
2、项目构成
2.1 概览
本脚手架使用 Maven3.8 打包,基于 Java11。包含 SpringBoot2.5.1 与 SpringCloud Alibaba2021 版本。将模块分为三大部分
common:项目中所有静态资源且需要与使用者共享的,如所有 Pojo,枚举,公共接口、公共工具包等
feign:项目对外开放的接口,即 controller 层的映射
server:项目自身的 boot 项目,包括所有的逻辑、交互
对于开发者,common 和 feign 中的 Maven 依赖不允许私自修改。
对于外部调用者,其 server 的 pom.xml 中永远只调用 common 和 feign,不允许调用这个服务与服务的 server 部分。
2.2 依赖表
主依赖
org.jetbrains
annotations
24.0.1
common 包依赖
com.yinginx
yinginx-common-base
feign 包依赖
com.yinginx
archetype-common
1.0.0-SNAPSHOT
com.yinginx
yinginx-common-web
io.github.openfeign
feign-okhttp
org.springframework.cloud
spring-cloud-starter-openfeign
server 包依赖
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
junit
junit
test
org.springframework.boot
spring-boot-configuration-processor
org.springframework.cloud
spring-cloud-starter-bootstrap
org.springframework.cloud
spring-cloud-dependencies
2020.0.3
pom
com.alibaba.nacos
nacos-client
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-config
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2021.1
pom
import
org.springframework.cloud
spring-cloud-starter-loadbalancer
com.yinginx
yinginx-common-base
com.yinginx
yinginx-common-web
com.yinginx
yinginx-common-util
mysql
mysql-connector-java
8.0.28
org.mybatis
mybatis-typehandlers-jsr310
1.0.1
com.baomidou
mybatis-plus
3.5.3.1
com.baomidou
mybatis-plus-boot-starter
3.5.3.1
org.springframework.amqp
spring-amqp
org.springframework.integration
spring-integration-mqtt
5.5.16
org.springframework.data
spring-data-redis
org.springframework.boot
spring-boot-starter-data-redis
org.springframework
spring-websocket
io.swagger
swagger-models
1.6.2
io.springfox
springfox-swagger2
3.0.0
io.springfox
springfox-swagger-ui
3.0.0
com.github.xiaoymin
knife4j-spring-boot-starter
3.0.3
io.springfox
springfox-boot-starter
3.0.0
com.alibaba
fastjson
1.2.83
org.apache.commons
commons-collections4
4.4
org.apache.commons
commons-lang3
org.apache.commons
commons-pool2
com.yinginx
archetype-common
1.0.0-SNAPSHOT
2.3 目录树
├─archetype-common
│ └─src
│ └─main
│ └─java
│ └─com.yinginx.liangang
│ ├─constant (所有对外共享的常量,枚举,数字、字符串、接口等)
│ ├─dto (所有 Data Transport Object,包括入参、中间参数)
│ ├─query (所有查询条件)
│ └─vo (所有视图返回体)
├─demo-feign
│ └─src
│ └─main
│ └─java
│ └─com.yinginx.liangang
│ ├─client (所有对外开放的 feign 接口)
│ └─fallback (每个 feign 接口对应的降级实现类)
└─demo-server
└─src
├─main
│ ├─java
│ │ └─com.yinginx.liangang
│ │ ├─aspect (切面层)
│ │ ├─config (所有配置项)
│ │ ├─controller (视图层)
│ │ ├─entity (实体层)
│ │ ├─mapper (数据库层)
│ │ ├─job (定时任务)
│ │ ├─service (服务层)
│ │ │ └─impl
│ │ ├─utils (工具包)
│ │ ├─DatabaseOutput.java (数据库表结构导出工具)
│ │ └─ServerApplication.java (主服务启动类)
│ └─resources
│ ├─mapper (数据映射层)
│ ├─bootstrap.yml (启动配置项)
│ └─logback-spring.xml (日志管理)
└─test
└─java
└─com.yinginx.liangang
3. 开发规范
3.1 constant
constant 包中应包含所有的对外共享的常量、枚举、接口等。用以申明固定不变的内容。
常量
常量通常包含:
项目中需要对外共享的 Redis-Key,此处建议能在编写时明确告知此 key 的 redis 类型。
项目中需要用到、且不适合枚举表示的,如电气交互点位编码等。
规范:
常量类中只允许申明常量!不能有类方法、公共构造函数等。
常量类应按功能进行区分,设置多个常量类。不能只写一个类申明所有常量。
枚举
枚举必须继承自 BaseEnum 类,并按要求实现 getDescription 方法。
此方法表示此枚举对应的中文含义。
规范:
在系统中,所有的枚举均需要以枚举本身进行传递,不允许使用 description。此值仅在最终呈现到用户时(包括接口正常显示和异常消息提示)需要转义为中
文。
在枚举值等值判断时,不允许使用 equals()方法,而是==。前者可能存在 NullPointerException。
public enum FrontendType implements BaseEnum {
SELECT("下拉菜单"),
INPUT("输入框"),
TEXT_AREA("文本域"),
INPUT_NUMBER("数字输入框"),
SWITCH("开关")
;
public final String description;
FrontendType(String description) {
this.description = description;
}
@Override
public String getDescription() {
return description;
}
}
接口
当服务需要对外暴露一些接口,使其他服务中的某些类也能适配此服务的一些约定,从而能实现更广泛的兼容。
规范:
不允许以抽象类的形式申明,只能申明接口!
原则上,这些接口只是一个约定,不应参与其他模块的业务。
3.2 dto
dto 包中包含所有的数据传输对象,包括服务中的所有入参和中间参数。此处的入参也包含调用第三方接口时的入参。
规范:
所有需要录入数据库的 DTO 都需要继承自 BaseDTO。其中包含了部分必须字段,如 id、createTime、updateTime、createUser、
updateUser,但这些 字段都是自动注入的,业务层无需关注。
在 dto 中,除了字段本身的 get set 方法、equals hashCode toString、实现的接口方法外,不允许有其他额外的方法;至少要提供一个无参构造函
数,有参构造函数自己决定。
在 dto 中,所有的非静态字段均需要使用包装类型,不允许使用原始类型。
在 dto 中,类名上需要带有@ApiModel 注解,并填入参数,以表示此类的作用对象;每个非静态字段需要带有@ApiModelProperty 注解,并填入参数,以
表示此字段的含义,同时需要在必填字段上申明 required 为 true。
在 dto 中,默认值的实现应通过改写其 get 方法进行判空,而不是直接在类申明时就进行赋值。部分框架如果参数中写了 null 也会进行赋值,导致默认值丢失。
在 dto 中,最好对入参进行校验使用 javax.validation 相关的注解,实现对接口入参的校验。
扩展:
common 包中还提供了一个扩展版本 LogicalDeletableDTO,添加了对 code、name、activate 和 deleted 的支持。如果业务字段确有需求,请继承
此版本,以保持统一。
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("工装")
public class ContainerBaseDTO extends LogicalDeletableDTO implements Serializable {
private static final long serialVersionUID = 5487478798652024128L;
@ApiModelProperty(value = "工装主类型ID", required = true)
@NotBlank(message = "工装主类型不得为空")
private String containerId;
@ApiModelProperty(value = "是否为虚拟工装", required = true)
@NotNull(message = "是否为虚拟工装不得为空")
private Boolean isVirtual;
}
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("绑定关系")
public class RelationshipDTO extends BaseDTO implements Serializable {
private static final long serialVersionUID = -3423399419564781643L;
@ApiModelProperty("位置ID")
@NotBlank(message = "位置不得为空")
private String positionId;
@ApiModelProperty("位置类型,storagePosition:储位,containerPosition:工装储位")
@NotBlank(message = "位置类型不得为空")
private String positionType;
@ApiModelProperty("存放的类型,container:工装,material:物料,tool:刀具...")
@NotBlank(message = "目标类型不得为空")
private String targetType;
@ApiModelProperty("绑定ID")
@NotBlank(message = "目标不得为空")
private String targetId;
}
3.3 query
query 包中包含所有的查询条件。所有查询条件默认均是分页查询所用。
规范:
所有需要录入数据库的 DTO 都需要继承自 BaseQuery。绝大部分性质与 dto 相同。
LogicalDeletableQuery 中明确了,不支持 deleted 字段的条件查询
扩展:
BaseQuery 中提供了 columns 的字段,以表示此次查询所需返回的字段。不包含在内的将返回 null。如果不传则默认全量查询。注意,此功能将直接影
响生成的 SQL 语句,因此错误的传参会导致查询失败!
BaseQuery 中提供了 orders 的字段,以表示此次查询的排序方案。如果不传则默认是 createTime 倒序。
BaseQuery 中提供了@QueryWrapper,添加在字段上可改写其查询方案与字段映射。具体查询方案对字段的数据类型会有要求。当使用默认的分页查询时,
此处的逻辑将会触发。详细见分页查询。
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("储位")
public class StoragePositionQuery extends LogicalDeletableQuery implements Serializable {
private static final long serialVersionUID = -6721672746626602583L;
@ApiModelProperty("仓位ID")
private String storageBaseId;
@ApiModelProperty("仓位编码")
private String storageBaseCode;
@ApiModelProperty("储位组ID")
private String storagePositionGroupId;
@ApiModelProperty(value = "是否为虚拟储位", required = true)
private Boolean isVirtual;
@ApiModelProperty(value = "可放置的目标类型", required = true)
@QueryWeapper(SqlConditions.IN)
private List availableTargetType;
@ApiModelProperty(value = "可放置的目标类型ID列表", required = true)
@QueryWeapper(SqlConditions.IN)
private List availableTargetIds;
@ApiModelProperty(value = "电气代号", required = true)
private Integer electricalCode;
@ApiModelProperty("绑定设备ID")
private String equipmentId;
@ApiModelProperty("产线ID")
private String factoryModelId;
}
3.4 vo
vo 包中包含所有的视图层返回体。所有的 vo 禁止使用在参数输入!此处的返回体也包含调用第三方接口时的返回体。
规范:
所有需要录入数据库的 VO 都需要继承自 BaseVO。绝大部分性质与 dto 相同。
BaseVO 中提供了@ExcelWrapper,添加在字段上可改写其在导出为 excel 时的字段标题映射。当使用 excel 导出时,此处的逻辑将会触发。
扩展:
BaseVO 默认实现了 BasePOJO,并在返回时可以附带类型信息,此举可以解决远程调用后的类型丢失问题,保证 feign 调用后依然能保持原类型与字段。原则上
所有的 vo 都需要带有。如果第三方接口无法提供此功能,或提供的字段无法在项目中进行反序列化,请不要继承 BaseVO,强行继承将导致报错。
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel("工装储位")
public class ContainerPositionVO extends LogicalDeletableVO implements PositionVO, Serializable {
private static final long serialVersionUID = 93441404971685544L;
@ApiModelProperty("位置类型")
private String positionType;
@ApiModelProperty("所属工装ID")
@ExcelWrapper(included = ExcelFieldInclude.IGNORED)
private String containerBaseId;
@ApiModelProperty("所属工装编码")
private String containerBaseCode;
@ApiModelProperty("所属工装名称")
private String containerBaseName;
@ApiModelProperty(value = "可存放的目标类型", required = true)
@ExcelWrapper(parser = "new com.smartstate.common.base.excel.ExcelFieldCollectionHandler()")
private List availableTargetType;
@ApiModelProperty(value = "可存放的目标类型ID列表", required = true)
@ExcelWrapper(included = ExcelFieldInclude.IGNORED)
private List availableTargetIds;
@ApiModelProperty(value = "电气代号", required = true)
private Integer electricalCode;
}
3.5 client
client 包中包含了所有本服务对外暴露的 API。
规范:
由于 controller 层的返回值会自动包装一层 ResultVO,因此在写 client 时需要为返回值手动包装一次。
扩展:
与 common 一样,client 也拥有 BaseClient 与 LogicalDeletableClient 两个版本,对标 controller。
@FeignClient(name = "yinginx-logistics", path = "/containerBase", fallbackFactory = ContainerBaseFallback.class)
public interface ContainerBaseClient extends LogicalDeletableClient {
}
3.6 fallback
fallback 包中包含了所有 client 对应的服务降级处理。
规范:
fallback 需要继承自 BaseFallback。与旧版的不同,新版本不再需要实现方法。
@Component
public class ContainerBaseFallback extends BaseFallbackFactory {
}
3.7 controller
视图层,所有对外开放的接口需要在此定义。
规范:
与 common 一样,controller 也拥有 BaseController 与 LogicalDeletableController 两个版本,对标 dto、vo、query。
在 BaseController 中提供了如下的接口:
getPage:标准分页查询,支持使用@QueryWrapper 进行自定义查询条件,支持 columns 进行返回字段限制,支持 orders 进行排序方式定制。
getById:根据 ID 单个查询。
getAll:全量查询。
getByIds:根据 ID 批量查询。
save:新增,并返回新增后的数据。
update:更新。
delete:根据 ID 批量删除。
exportExcel:导出为 excel,支持使用@ExcelWrapper 进行自定义字段名映射。详情见 excel 导出。
在定义接口时,请利用好@Validation,完成对入参的校验,减少在业务中校验入参。
@RestController
@RequestMapping("/api//containerBase")
@Api(tags = "工装")
public class ContainerBaseController extends LogicalDeletableController {
private final ContainerBaseService containerBaseService;
public ContainerBaseController(ContainerBaseService containerBaseService) {
this.containerBaseService = containerBaseService;
}
@Override
public @NotNull ContainerBaseService getService() {
return containerBaseService;
}
}
在接口上,共有两个注解可以使用。
@ApiResultWrapper 用于对返回值进行包装。在默认情况下,无需注解,就会对正常返回值进行一次 ResultVO 包装,并放入 data 字段中。如果抛出了
异常,则会将异常信息放入 message 字段中。如果添加了注解,则可以自定义成功状态下的 messae(不加的话就是没有);或可以使用 ignore 直接取消此
接口的自动包装。
@ApiBodyWrapper 用于对接口的响应参数进行处理展示。在默认情况下,无需注解,就会对接口的入参、出参进行打印。如果添加了注解,则可以改写此方案
,从而自定义处理方案(包括什么也不做的)。当然,也可以通过配置项 server.api-body-interceptor = false,直接禁用此套逻辑。
3.8 entity
实体层,所有数据映射对象需要在此定义。
规范:
所有 Entity 都需要继承自 BaseEntity。绝大部分性质与 dto 相同。
此版本中默认不再包含 JPA 组件,因此请手动建表、维护。
BaseEntity 本身的字段无需在业务层关心。
由于动态扩展列的加入,所有的实体均需要添加@TableName(autoResultMap = true)。
@Data
@EqualsAndHashCode(callSuper = true)
@TableName(autoResultMap = true)
public class ContainerBase extends LogicalDeletableEntity implements Serializable {
private static final long serialVersionUID = 3428868220977156789L;
private String containerId;
private Boolean isVirtual;
}
3.9 mapper
数据库映射层,所有与数据库之间的交互在此编写。
我们仍推荐简单的增删改查使用默认的方法完成,此处只推荐使用复杂查询时的场景。
3.10 service
服务层,所有正式的业务逻辑在此编写。原则上,应保证每个服务尤其独立的接口与实现,且其他类遵循面向接口开发的原则,不得依赖具体的实现类。
服务层中,对 controller 层相关接口进行了实现,提供了数据层的增删改查。
规范:
与 common 一样,service 也拥有 BaseService 与 LogicalDeletableService 两个版本。
对外开放的接口,应确认好出参入参的空与非空,并通过注解@NotNull、@Nullable 进行明确表示。默认情况下,入参没有@NotNull 表示可以传
null,出参可能是 null 时必须有@Nullable。
异常抛出见异常处理。
public interface ContainerBaseService extends LogicalDeletableService {
List queryContainerBaseByParentIds(@NotNull Collection parentIds);
}
@Service
@Transactional(rollbackFor = Exception.class)
public class ContainerBaseServiceImpl
extends LogicalDeletableServiceImpl
implements ContainerBaseService {
}
getPage
输入分页查询参数后,会根据其字段有无与查询条件,自动拼装查询 SQL,并根据 columns 和 orders 进行排序和字段过滤。
如果实际字段与数据库字段不同的,就需要@QueryWrapper 进行转义,如果字段上没有此注解则表示使用默认字段名。
此后统一对所有字段进行处理,将大驼峰格式改为下划线格式。
对于查询字段,如果不传则为全量,否则按字段返回。
对于排序字段,如果不传则为 createTime 倒序,否则按传入的顺序与方式进行排序。
最近进行统一查询。
exportExcel
在分页的基础上,会把返回体输出至 excel 中。
如果实际字段与原本的字段名不一样的,就需要@ExcelWrapper 进行转义,如果字段上没有此注解则表示使用默认字段名。
按此方法对所有对象进行递归,获取所有字段后按行输出结果。(首行是标题)
3.11 其他改进
异常
在 common 包中,提供了新的 BaseException 以及 4 个默认实现,以替代旧版的 CommonException,可以满足基本场景下的异常抛出需求。在业务编写过程中,
可以使用其静态构造函数完成异常的创建与抛出。脚手架中集成了完整的全局异常处理,涵盖了接口部分和定时任务部分。
由于 BaseException 是 RuntimeException,因此使用者需要自己注意所调用的代码是否抛出业务异常,是否需要捕获。
在新的异常体系中,异常支持动态参数拼接,与 log 的用法一致。
class ExceptionDemo {
public static void main(String[] args) {
throw OperationFailedException.of("工件 {} 出线异常: {}", materialCode, exceptionMessage);
}
}
redis
在新版本的 redisTemplate,会类型记录机制,对所有的数据类型进行记录,从而实现了抽象类型的类型保持。由于类型记录需要其根本对象继承自 BasePOJO
,因 此在实际存入读取的过程中,如果对象不是 BasePOJO 的子类,则会在存入时自动包装一个 PojoReference,取出时自动拆除。
typehandler
在新版本中,统一对数据库层面的 json 格式提供了支持,即支持 Mysql 的 JSON 字段类型。但由于 JSON 不被 Mybatis 支持,因此,当使用这种字段时需要额外配置
typehandler。
在 common 包中,提供了 ListToStringTypeHandler,用来处理 JSON 中存放简单的数组的情况。即 List、List、
List等列表中只含有基础类型的情况。提供了 MapToStringTypeHandler,用来处理 JSON 中存放简单对象的情况。其余情况建议重新建表进行存
储。
如何使用:
Mybatis-Plus 版本(即在实体上需要)
import java.util.List;
class Entity extends BaseEntity {
@TableField(typehandler = ListToStringTypeHandler.class)
private List jsonField;
}
Mybatis 版本(如果查询的时候是走 xml 配置的,那么需要在 resultMap 中进行改写)
serialUtil
在新版本中,对流水号的生成器做了很大的改动。支持与 log 一样的模板填参方式,进行序列号的自定义生成。
@Component
@SuppressWarnings("unused")
public class SerialUtil {
@Resource
private RedisTemplate redisTemplate;
/**
* 前缀+8位时间+4位流水号
*
* @param prefix 前缀
* @return 生成的流水号
*/
public final String prefixTimestampSerialNumber(String prefix) {
return getSerial(
"{}{}{}",
new StringSerial(prefix),
new DateTimeSerial(new SimpleDateFormat("yyyyMMdd")),
new RedisSerialNumberSerial(redisTemplate, prefix, 4, RedisSerialNumberSerial.EXPIRE_EVERY_DAY)
);
}
/**
* 前缀+4位流水号
*
* @param prefix 前缀
* @return 生成的流水号
*/
public final String prefixSerialNumber(String prefix) {
return getSerial(
"{}{}",
new StringSerial(prefix),
new RedisSerialNumberSerial(redisTemplate, prefix, 4, RedisSerialNumberSerial.NEVER_EXPIRE)
);
}
/**
* 自定义流水号生成器。
*
* @param template 模板
* @param args 生成方法
* @return 生成的流水号
*/
public final String getSerial(String template, SerialSupplier... args) {
return LogParameterHelper.logParameterHelper(template, args);
}
}
接口优化
在新版本中,延续了之前的 ResultVO 自动封装,并修复了对于 String 的问题,同时提供了一个新的方法,以自动判断接口调用是否成功。
public final class ResultVO implements BasePOJO, Serializable {
@JSONField(serialize = false, deserialize = false)
@JsonIgnore
public T getDataOrException() {
if (isSuccess()) {
return data;
}
throw FeignException.of(message, serviceName);
}
}
此外,还添加了对于接口出参入参的打印。由于 spring mvc 的限制,此功能无法正常打印非 json 格式的内容,如数据流等。
Websocket
在新版本中,对 websocket 提供了支持。实现 BaseWebsocket 抽象类,并在类上申明 Websocket 即可申明一个 ws 路径,将其注册为一个 bean,即可。
@Component
@Websocket("/ws")
public final class Ws extends BaseWebsocket {
@Override
public @Nullable CloseStatus onOpen(WebSocketSession session, Map attributes) {
log.info("someone entered");
return null;
}
@Override
public CloseStatus onMessage(WebSocketSession session, WsDTO inputData) {
log.info("received message {}", inputData.getData());
return null;
}
@Override
public CloseStatus onError(WebSocketSession session, Throwable exception) {
log.warn("received error", exception);
return null;
}
@Override
public void onClose(WebSocketSession session, CloseStatus closeStatus) {
log.info("someone left");
}
}
ProjectSchedule
在新版本中,提供了注解@ProjectScheduled,用于表示这是一个项目级定时任务。
即项目级定时任务。通过获取配置文件中的 global.projectName,获取此时所处的位置,并与直接上的 projectName 进行匹配,如果任意一项符合,则启动
此定时任务。如果 projectName 为空数组,则表示不匹配,永远启动。
注解使用方法与普通的@Scheduled 一致,且都是在项目启动时自动注入。仅多了上述一个字段的区别。
Redis Lock
在新版本中,提供了一个注解@Distributed,当注释在方法上,表示此方法需要启用分布式锁。实现逻辑:
指定一个 value,以表示将此 key 作为 redis 的 key,进行锁的管理。当此 key 存在时,无法获取锁。 如果指定了 waitTime,则获取锁会在等待指定秒后失败,并
执行 timeoutHandler 的回调;否则,线程会一直阻塞,直到获取锁。获取锁之后,才会开始执行方法,同时开启一个定时任务,进行锁的续约,每次锁只会保持
两秒,并每秒进行一次续约。方法执行完毕后,会释放锁,并结束定时任务;或在超时后,由 redis 自行释放。 因此,这样的实现可以保证服务挂掉后,其余的服务
可以正常的接手此 key。
建议:
每次的锁定时间大于触发间隔时,近似可以认为此服务独占此锁,当服务挂掉后下一服务可以立即接手。
续约间隔一定要小于锁定时间,否则锁可能自己就过期解开了!
要求:必须是通过代理对象调用此方法才能生效,类自身调用是不生效的!因为本质是 AOP。
如果无法放在方法上,或不能使用代理对象,则可以手动创建 RedisLock,并手动进行加解锁。
后续的所有方法都不是 bean!
Mqtt client
通过构建一个 MqttClientConnect,可以快速的申明一个 mqtt 连接,通过配置相关的参数即可实现消息的收发。
DateTimeMapper
时间与字符串之间的转换器,以及特殊时间的相关快速获取方式。
DtoMapper
4.1 版本已标注为废弃,4.2 版本将移除
实体的字段转换器。内核是 Spring BeanUtil,对嵌套实体的支持尚有问题,请注意。
BeanCopierFactory
DtoMapper 的替代工具
支持了嵌套对象的转换。但以下是几种字段特殊情况:
无法转换类型不同的情况,如源字段类型是原始类型,目标字段是包装类型,反之亦然。或是可以通过类型的强转达成的类型。
无法转换源类型是目标类型父类的情况。反之可以。
如果源类型/目标类型是泛型的,由于类型擦除,即使泛型参数不一致也可以转换,但是会在取出时报错。
FTPUtil
FTP 的工具包,用于实现连接,并进行文件的上传下载。
HttpUtil
用于发起 Http 请求。
通过链式调用,从而满足一次配置,反复请求的目的。
IotUtil
在 HttpUtil 的基础上,封装了 Iot 的写入读取功能。
并在其基础上,进一步提供了标准配方写入(formulationWrite)和阻塞读取(blockUntil)功能。
PagesUtil
分页的一些小工具。
StoppableSchedule
静态的定时任务管理工具。
4、开始编码
生成结构后,需要改哪些东西?哪些不能删除
类 ServerApplication,建议改名,以更好的区分项目启动。
DynamicTableExtension 相关的内容,包括 FrontendType 不能删除。feign 包中的除外。
DatabaseOutput,如果需要导出,可以在执行前进行配置项的修改。
bootstrap.yml 中,需要把 spring.application.name 和 extension-configs 修正。
logback-spring.xml 中,需要把 projectName 和 moduleName 修正。
migrate.sql 中用于存放此模块的建表 SQL。