一顿优化IdGeneratorService

This commit is contained in:
Turbolisten 2021-10-16 18:27:06 +08:00
parent 7295b90320
commit 98d80a0a03
15 changed files with 236 additions and 160 deletions

View File

@ -12,13 +12,12 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* [ admin 项目启动类 ] * [ admin 项目启动类 ]
* *
* @author 罗伊 * @author 罗伊
*
*/ */
@SpringBootApplication @SpringBootApplication
@EnableCaching @EnableCaching
@EnableScheduling @EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) @EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@MapperScan(value = "net.lab1024.smartadmin.service.*",annotationClass = Mapper.class) @MapperScan(value = "net.lab1024.smartadmin.service.*", annotationClass = Mapper.class)
public class SmartAdminApplication { public class SmartAdminApplication {
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -18,7 +18,7 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component; import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -39,7 +39,7 @@ import java.util.Map;
* @date 2020/8/25 11:57 * @date 2020/8/25 11:57
*/ */
@Slf4j @Slf4j
@Component @Configuration
@ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "cloud") @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "cloud")
public class FileStorageCloudServiceImpl implements IFileStorageService { public class FileStorageCloudServiceImpl implements IFileStorageService {

View File

@ -12,7 +12,7 @@ import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component; import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -28,7 +28,7 @@ import java.io.InputStream;
* @date 2020/8/25 11:57 * @date 2020/8/25 11:57
*/ */
@Slf4j @Slf4j
@Component @Configuration
@ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "local") @ConditionalOnProperty(prefix = "file.storage", name = {"mode"}, havingValue = "local")
public class FileStorageLocalServiceImpl implements IFileStorageService { public class FileStorageLocalServiceImpl implements IFileStorageService {

View File

@ -27,7 +27,7 @@ public class IdGeneratorController extends SupportBaseController {
@Autowired @Autowired
private IdGeneratorService idGeneratorService; private IdGeneratorService idGeneratorService;
@ApiOperation("生成id") @ApiOperation("生成id by listen")
@GetMapping("/id/generator/{generatorId}") @GetMapping("/id/generator/{generatorId}")
public ResponseDTO<String> generate(@PathVariable Integer generatorId) { public ResponseDTO<String> generate(@PathVariable Integer generatorId) {
IdGeneratorEnum idGeneratorEnum = SmartBaseEnumUtil.getEnumByValue(generatorId, IdGeneratorEnum.class); IdGeneratorEnum idGeneratorEnum = SmartBaseEnumUtil.getEnumByValue(generatorId, IdGeneratorEnum.class);

View File

@ -1,32 +1,17 @@
package net.lab1024.smartadmin.service.module.support.idgenerator; package net.lab1024.smartadmin.service.module.support.idgenerator;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity; import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordDTO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
/** /**
* zhuo * id生成 dao
*
* @author zhuo
*/ */
@Mapper @Mapper
@Component @Component
public interface IdGeneratorDao { public interface IdGeneratorDao extends BaseMapper<IdGeneratorEntity> {
List<IdGeneratorEntity> selectAll();
int replaceIdGeneratorRecord(@Param("generatorId") Integer generatorId,
@Param("year") int year,
@Param("month") int month,
@Param("day") int day,
@Param("lastNumber") Long lastNumber,
@Param("count") long count);
IdGeneratorRecordDTO selectHistoryLastNumber(@Param("generatorId") Integer generatorId,
@Param("year") int year,
@Param("month") int month,
@Param("day") int day);
} }

View File

@ -0,0 +1,26 @@
package net.lab1024.smartadmin.service.module.support.idgenerator;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
/**
* id生成 dao
*
* @author zhuo
*/
@Mapper
@Component
public interface IdGeneratorRecordDao extends BaseMapper<IdGeneratorRecordEntity> {
/**
* 查询id最后生成记录
*
* @param generatorId
* @param timeFormat
* @return
*/
IdGeneratorRecordEntity selectHistoryLastNumber(@Param("generatorId") Integer generatorId, @Param("time") String timeFormat);
}

View File

@ -13,15 +13,13 @@ import net.lab1024.smartadmin.service.common.enumeration.BaseEnum;
@Getter @Getter
public enum IdGeneratorEnum implements BaseEnum { public enum IdGeneratorEnum implements BaseEnum {
ORDER(1, "订单id"),
CONTRACT(2, "合同id"),
; ;
private final Integer value; private final Integer value;
private final String desc; private final String desc;
@Override
public String toString() {
return "IdGeneratorEnum{" + "id=" + value + ", keyName='" + desc + '\'' + '}';
}
} }

View File

@ -2,6 +2,7 @@ package net.lab1024.smartadmin.service.module.support.idgenerator.constant;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import net.lab1024.smartadmin.service.common.constant.StringConst;
import net.lab1024.smartadmin.service.common.enumeration.BaseEnum; import net.lab1024.smartadmin.service.common.enumeration.BaseEnum;
/** /**
@ -15,7 +16,7 @@ public enum IdGeneratorRuleTypeEnum implements BaseEnum {
/** /**
* 没有周期 * 没有周期
*/ */
NO_CYCLE("", "没有周期"), NO_CYCLE(StringConst.EMPTY_STR, "没有周期"),
/** /**
* 年周期 * 年周期
*/ */

View File

@ -4,8 +4,9 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum;
import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
@ -15,22 +16,20 @@ import java.time.LocalDateTime;
*/ */
@Data @Data
@TableName("t_id_generator") @TableName("t_id_generator")
public class IdGeneratorEntity implements Serializable { public class IdGeneratorEntity {
private static final long serialVersionUID = 5582354131134766548L;
/** /**
* 主键id * 主键id
* *
* @see net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum * @see IdGeneratorEnum
*/ */
@TableId(type = IdType.AUTO) @TableId(type = IdType.INPUT)
private Integer id; private Integer id;
/** /**
* 英文key * 业务
*/ */
private String keyName; private String businessName;
/** /**
* 前缀 * 前缀
@ -38,15 +37,17 @@ public class IdGeneratorEntity implements Serializable {
private String prefix; private String prefix;
/** /**
* 最低补位长度 * 生成规则
*/ *
private Integer minLength; * @see IdGeneratorRuleTypeEnum
/**
* 类型
*/ */
private String ruleType; private String ruleType;
/**
* 最低生成id长度
*/
private Integer minLength;
/** /**
* 初始值 * 初始值
*/ */

View File

@ -1,5 +1,8 @@
package net.lab1024.smartadmin.service.module.support.idgenerator.domain; package net.lab1024.smartadmin.service.module.support.idgenerator.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -10,15 +13,15 @@ import java.time.LocalDateTime;
* @Description: * @Description:
*/ */
@Data @Data
public class IdGeneratorRecordDTO { @TableName("t_id_generator_record")
public class IdGeneratorRecordEntity {
@TableId(type = IdType.AUTO)
private Long id;
private Integer generatorId; private Integer generatorId;
private Integer year; private String time;
private Integer month;
private Integer day;
private Long lastNumber; private Long lastNumber;

View File

@ -1,28 +1,29 @@
package net.lab1024.smartadmin.service.module.support.idgenerator.service; package net.lab1024.smartadmin.service.module.support.idgenerator.service;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.lab1024.smartadmin.service.common.code.UnexpectedErrorCode;
import net.lab1024.smartadmin.service.common.code.UserErrorCode;
import net.lab1024.smartadmin.service.common.constant.RedisKeyConst;
import net.lab1024.smartadmin.service.common.domain.ResponseDTO;
import net.lab1024.smartadmin.service.common.exception.BusinessException; import net.lab1024.smartadmin.service.common.exception.BusinessException;
import net.lab1024.smartadmin.service.common.util.SmartRandomUtil; import net.lab1024.smartadmin.service.common.util.SmartRandomUtil;
import net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorDao; import net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorDao;
import net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorRecordDao;
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum; import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum; import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorRuleTypeEnum;
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity; import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity;
import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordDTO; import net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity;
import net.lab1024.smartadmin.service.third.SmartRedisService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -34,28 +35,25 @@ import java.util.stream.Collectors;
@Service @Service
public class IdGeneratorService { public class IdGeneratorService {
private static final int MAX_GET_LOCK_COUNT = 5; private static final Interner<Integer> POOL = Interners.newWeakInterner();
private static final long SLEEP_MILLISECONDS = 500L;
private static volatile long lastSleepMilliSeconds = SLEEP_MILLISECONDS;
private ConcurrentHashMap<Integer, IdGeneratorEntity> idGeneratorMap;
@Autowired @Autowired
private IdGeneratorDao idGeneratorDao; private IdGeneratorDao idGeneratorDao;
@Autowired @Autowired
private SmartRedisService redisService; private IdGeneratorRecordDao idGeneratorRecordDao;
private Map<Integer, IdGeneratorEntity> idGeneratorMap;
@PostConstruct @PostConstruct
void init() { public void init() {
List<IdGeneratorEntity> idGeneratorEntityList = idGeneratorDao.selectAll(); List<IdGeneratorEntity> idGeneratorEntityList = idGeneratorDao.selectList(null);
idGeneratorMap = idGeneratorEntityList.stream().collect(Collectors.toMap(IdGeneratorEntity::getId, Function.identity(), (x, y) -> y, ConcurrentHashMap::new)); idGeneratorMap = idGeneratorEntityList.stream().collect(Collectors.toMap(IdGeneratorEntity::getId, Function.identity()));
log.info("##################### init IdGenerator #####################");
} }
/** /**
* id 生成 * id生成
* *
* @param idGeneratorEnum 类型 * @param idGeneratorEnum 类型
* @return * @return
@ -64,84 +62,78 @@ public class IdGeneratorService {
int generatorId = idGeneratorEnum.getValue(); int generatorId = idGeneratorEnum.getValue();
IdGeneratorEntity idGeneratorEntity = this.idGeneratorMap.get(generatorId); IdGeneratorEntity idGeneratorEntity = this.idGeneratorMap.get(generatorId);
if (null == idGeneratorEntity) { if (null == idGeneratorEntity) {
throw new BusinessException("IdGenerator 生成器 不存在 " + idGeneratorEnum.getDesc()); throw new BusinessException("IdGenerator生产业务不存在 " + idGeneratorEnum.getDesc());
}
// 校验生成规则
IdGeneratorRuleTypeEnum ruleTypeEnum = this.getIdGeneratorRuleTypeEnum(idGeneratorEntity.getRuleType());
Assert.notNull(ruleTypeEnum, "IdGenerator rule type 不存在 " + idGeneratorEntity.getRuleType());
// 默认起始值
Long startNumber = idGeneratorEntity.getInitNumber();
// 判断是否有循环规则
String timeFormat = null;
DateTimeFormatter timeFormatter = null;
if (IdGeneratorRuleTypeEnum.YEAR_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.MONTH_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.DAY_CYCLE == ruleTypeEnum) {
timeFormatter = DateTimeFormatter.ofPattern(ruleTypeEnum.getValue());
timeFormat = LocalDateTime.now().format(timeFormatter);
} }
// 获取全局唯一锁 synchronized (POOL.intern(generatorId)) {
String lockKey = RedisKeyConst.Support.ID_GENERATOR + idGeneratorEnum.getDesc(); // 获取最后一次生成记录
boolean lock = false; boolean isFirst = false;
for (int i = 0; i < MAX_GET_LOCK_COUNT; i++) { IdGeneratorRecordEntity recordEntity = idGeneratorRecordDao.selectHistoryLastNumber(generatorId, timeFormat);
try { if (recordEntity == null) {
//60秒 recordEntity = new IdGeneratorRecordEntity();
lock = redisService.getLock(lockKey, 60 * 1000L); recordEntity.setGeneratorId(generatorId);
if (lock) { recordEntity.setTime(timeFormat);
break; recordEntity.setLastNumber(startNumber);
} recordEntity.setCount(1L);
Thread.sleep(Math.max(SLEEP_MILLISECONDS, lastSleepMilliSeconds)); idGeneratorRecordDao.insert(recordEntity);
} catch (Throwable e) {
log.error(e.getMessage(), e);
}
}
if (!lock) {
throw new BusinessException("IdGenerator 生成器繁忙,无法处理: " + idGeneratorEnum.getDesc());
}
try { isFirst = true;
long beginTime = System.currentTimeMillis();
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int monthValue = now.getMonthValue();
int dayOfMonth = now.getDayOfMonth();
IdGeneratorRecordDTO generatorRecordDTO = idGeneratorDao.selectHistoryLastNumber(generatorId, year, monthValue, dayOfMonth);
if (generatorRecordDTO == null) {
generatorRecordDTO = new IdGeneratorRecordDTO();
generatorRecordDTO.setGeneratorId(generatorId);
generatorRecordDTO.setYear(year);
generatorRecordDTO.setMonth(monthValue);
generatorRecordDTO.setDay(dayOfMonth);
generatorRecordDTO.setLastNumber(idGeneratorEntity.getInitNumber());
generatorRecordDTO.setCount(0L);
generatorRecordDTO.setUpdateTime(now);
} }
Long lastNumber = generatorRecordDTO.getLastNumber(); // 没有循环 在同个循环周期内起始值 = 上次id
IdGeneratorRuleTypeEnum ruleTypeEnum = this.getIdGeneratorRuleTypeEnum(idGeneratorEntity.getRuleType()); if (IdGeneratorRuleTypeEnum.NO_CYCLE == ruleTypeEnum || Objects.equals(recordEntity.getUpdateTime().format(timeFormatter), timeFormat)) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(ruleTypeEnum.getValue()); startNumber = recordEntity.getLastNumber();
String nowFormat = now.format(formatter);
if (IdGeneratorRuleTypeEnum.YEAR_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.MONTH_CYCLE == ruleTypeEnum || IdGeneratorRuleTypeEnum.DAY_CYCLE == ruleTypeEnum) {
if (!Objects.equals(generatorRecordDTO.getUpdateTime().format(formatter), nowFormat)) {
lastNumber = idGeneratorEntity.getInitNumber();
}
} }
lastNumber += SmartRandomUtil.nextInt(1, idGeneratorEntity.getStepRandomRange()); // 在范围内随机生成此次增加的数值 更新id生成记录
long count = generatorRecordDTO.getCount() + 1; if (!isFirst) {
idGeneratorDao.replaceIdGeneratorRecord(generatorId, year, monthValue, dayOfMonth, lastNumber, count); startNumber += SmartRandomUtil.nextInt(1, idGeneratorEntity.getStepRandomRange());
IdGeneratorRecordEntity updateRecordEntity = new IdGeneratorRecordEntity();
updateRecordEntity.setId(recordEntity.getId());
updateRecordEntity.setLastNumber(startNumber);
updateRecordEntity.setCount(recordEntity.getCount() + 1);
idGeneratorRecordDao.updateById(updateRecordEntity);
}
// 格式化num 不足位数则补零 // 默认 最低长度 1
int minLength = idGeneratorEntity.getMinLength(); int minLength = NumberUtils.max(idGeneratorEntity.getMinLength(), 1);
minLength = minLength <= 0 ? 1 : minLength; // id长度补位
// 补位 String finalId = String.format("%0" + minLength + "d", startNumber);
String finalId = String.format("%0" + minLength + "d", lastNumber); if (null != timeFormat) {
String prefix = StringUtils.isBlank(idGeneratorEntity.getPrefix()) ? StringUtils.EMPTY : idGeneratorEntity.getPrefix(); finalId = timeFormat + finalId;
}
lastSleepMilliSeconds = System.currentTimeMillis() - beginTime + 100; // 前缀
return prefix + nowFormat + finalId; if (StringUtils.isNotBlank(idGeneratorEntity.getPrefix())) {
} catch (Throwable e) { finalId = idGeneratorEntity.getPrefix() + finalId;
log.error(e.getMessage(), e); }
throw e; return finalId;
} finally {
redisService.unLock(lockKey);
} }
} }
/**
* 查询生成规则
*
* @param ruleType
* @return 没有则返回null
*/
private IdGeneratorRuleTypeEnum getIdGeneratorRuleTypeEnum(String ruleType) { private IdGeneratorRuleTypeEnum getIdGeneratorRuleTypeEnum(String ruleType) {
for (IdGeneratorRuleTypeEnum en : IdGeneratorRuleTypeEnum.values()) { return Arrays.stream(IdGeneratorRuleTypeEnum.values())
if (en.name().equalsIgnoreCase(ruleType)) { .filter(e -> StringUtils.equalsIgnoreCase(e.name(), ruleType))
return en; .findFirst().orElse(null);
}
}
return null;
} }
} }

View File

@ -1,21 +0,0 @@
<?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="net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorDao">
<!-- 查询上次id -->
<select id="selectAll" resultType="net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorEntity">
select * from t_id_generator
</select>
<select id="selectHistoryLastNumber" resultType="net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordDTO">
select * from t_id_generator_record
where generator_id = #{generatorId} and year=#{year} and month=#{month} and day=#{day}
</select>
<update id="replaceIdGeneratorRecord">
REPLACE INTO t_id_generator_record (generator_id, `year`, `month`, `day`, last_number,`count`)
values (#{generatorId}, #{year}, #{month}, #{day}, #{lastNumber},#{count})
</update>
</mapper>

View File

@ -0,0 +1,31 @@
<?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="net.lab1024.smartadmin.service.module.support.idgenerator.IdGeneratorRecordDao">
<select id="selectHistoryLastNumber" resultType="net.lab1024.smartadmin.service.module.support.idgenerator.domain.IdGeneratorRecordEntity">
select * from t_id_generator_record
where generator_id = #{generatorId}
<if test="null != time">
and `time`= #{time}
</if>
ORDER BY id DESC LIMIT 1
</select>
<update id="replaceIdGeneratorRecord">
UPDATE t_id_generator_record
<set>
<if test="null != year">
and `year`= #{year}
</if>
<if test="null != month">
and `month`= #{month}
</if>
<if test="null != day">
and `day`= #{day}
</if>
</set>
where generator_id = #{generatorId}
</update>
</mapper>

View File

@ -0,0 +1,25 @@
package net.lab1024.smartadmin.service;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class SmartAdminApplicationTest {
@BeforeEach
public void before() {
System.out.println("----------------------- 测试开始 -----------------------");
}
@AfterEach
public void after() {
System.out.println("----------------------- 测试结束 -----------------------");
}
}

View File

@ -0,0 +1,36 @@
package net.lab1024.smartadmin.service.module.support.idgenerator.service;
import net.lab1024.smartadmin.service.SmartAdminApplicationTest;
import net.lab1024.smartadmin.service.module.support.idgenerator.constant.IdGeneratorEnum;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.CountDownLatch;
class IdGeneratorServiceTest extends SmartAdminApplicationTest {
@Autowired
private IdGeneratorService generatorService;
/**
* id 生成测试
*/
@Test
void generateTest() throws InterruptedException {
int thread = 10;
CountDownLatch countDownLatch = new CountDownLatch(thread);
Runnable task = () -> {
String id = generatorService.generate(IdGeneratorEnum.CONTRACT);
System.out.println(countDownLatch.getCount() + "生成id->" + id);
countDownLatch.countDown();
};
for (int i = 0; i < thread; i++) {
new Thread(task).start();
}
countDownLatch.await();
}
}