Commit 441fe1872099bab8ac1e999e484ece0b777fa4cf

Authored by YunaiV
1 parent 005d64aa

feat:【framework 框架】优化 jackson 的初始化

yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java
... ... @@ -75,7 +75,7 @@ public class TenantDatabaseInterceptor implements TenantLineHandler {
75 75 if (TenantBaseDO.class.isAssignableFrom(tableInfo.getEntityType())) {
76 76 return false;
77 77 }
78   - // 如果添加了 @TenantIgnore 注解,显然也不忽略租户
  78 + // 如果添加了 @TenantIgnore 注解,则忽略租户
79 79 TenantIgnore tenantIgnore = tableInfo.getEntityType().getAnnotation(TenantIgnore.class);
80 80 return tenantIgnore != null;
81 81 }
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/jackson/config/YudaoJacksonAutoConfiguration.java
1 1 package cn.iocoder.yudao.framework.jackson.config;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
5 4 import cn.iocoder.yudao.framework.common.util.json.databind.NumberSerializer;
6 5 import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeDeserializer;
7 6 import cn.iocoder.yudao.framework.common.util.json.databind.TimestampLocalDateTimeSerializer;
  7 +import com.fasterxml.jackson.databind.Module;
8 8 import com.fasterxml.jackson.databind.ObjectMapper;
9 9 import com.fasterxml.jackson.databind.module.SimpleModule;
10 10 import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
... ... @@ -13,39 +13,65 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
13 13 import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
14 14 import lombok.extern.slf4j.Slf4j;
15 15 import org.springframework.boot.autoconfigure.AutoConfiguration;
  16 +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
  17 +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
16 18 import org.springframework.context.annotation.Bean;
17 19  
18 20 import java.time.LocalDate;
19 21 import java.time.LocalDateTime;
20 22 import java.time.LocalTime;
21   -import java.util.List;
22 23  
23   -@AutoConfiguration
  24 +@AutoConfiguration(after = JacksonAutoConfiguration.class)
24 25 @Slf4j
25 26 public class YudaoJacksonAutoConfiguration {
26 27  
  28 + /**
  29 + * 从 Builder 源头定制(关键:使用 *ByType,避免 handledType 要求)
  30 + */
27 31 @Bean
28   - @SuppressWarnings("InstantiationOfUtilityClass")
29   - public JsonUtils jsonUtils(List<ObjectMapper> objectMappers) {
30   - // 1.1 创建 SimpleModule 对象
31   - SimpleModule simpleModule = new SimpleModule();
32   - simpleModule
33   - // 新增 Long 类型序列化规则,数值超过 2^53-1,在 JS 会出现精度丢失问题,因此 Long 自动序列化为字符串类型
34   - .addSerializer(Long.class, NumberSerializer.INSTANCE)
35   - .addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
36   - .addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)
37   - .addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
38   - .addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
39   - .addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
40   - // 新增 LocalDateTime 序列化、反序列化规则,使用 Long 时间戳
41   - .addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
42   - .addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
43   - // 1.2 注册到 objectMapper
44   - objectMappers.forEach(objectMapper -> objectMapper.registerModule(simpleModule));
  32 + public Jackson2ObjectMapperBuilderCustomizer ldtEpochMillisCustomizer() {
  33 + return builder -> builder
  34 + // Long -> Number
  35 + .serializerByType(Long.class, NumberSerializer.INSTANCE)
  36 + .serializerByType(Long.TYPE, NumberSerializer.INSTANCE)
  37 + // LocalDate / LocalTime
  38 + .serializerByType(LocalDate.class, LocalDateSerializer.INSTANCE)
  39 + .deserializerByType(LocalDate.class, LocalDateDeserializer.INSTANCE)
  40 + .serializerByType(LocalTime.class, LocalTimeSerializer.INSTANCE)
  41 + .deserializerByType(LocalTime.class, LocalTimeDeserializer.INSTANCE)
  42 + // LocalDateTime < - > EpochMillis
  43 + .serializerByType(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE)
  44 + .deserializerByType(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
  45 + }
45 46  
46   - // 2. 设置 objectMapper 到 JsonUtils
47   - JsonUtils.init(CollUtil.getFirst(objectMappers));
48   - log.info("[init][初始化 JsonUtils 成功]");
  47 + /**
  48 + * 以 Bean 形式暴露 Module(Boot 会自动注册到所有 ObjectMapper)
  49 + */
  50 + @Bean
  51 + public Module timestampSupportModuleBean() {
  52 + SimpleModule m = new SimpleModule("TimestampSupportModule");
  53 + // Long -> Number,避免前端精度丢失
  54 + m.addSerializer(Long.class, NumberSerializer.INSTANCE);
  55 + m.addSerializer(Long.TYPE, NumberSerializer.INSTANCE);
  56 + // LocalDate / LocalTime
  57 + m.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE);
  58 + m.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE);
  59 + m.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE);
  60 + m.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE);
  61 + // LocalDateTime < - > EpochMillis
  62 + m.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE);
  63 + m.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE);
  64 + return m;
  65 + }
  66 +
  67 + /**
  68 + * 初始化全局 JsonUtils,直接使用主 ObjectMapper
  69 + */
  70 + @Bean
  71 + @SuppressWarnings("InstantiationOfUtilityClass")
  72 + public JsonUtils jsonUtils(ObjectMapper objectMapper) {
  73 + JsonUtils.init(objectMapper);
  74 + log.debug("[init][初始化 JsonUtils 成功]");
49 75 return new JsonUtils();
50 76 }
51 77  
... ...
yudao-module-mall/yudao-module-promotion/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
... ... @@ -166,7 +166,7 @@ public class CouponServiceImpl implements CouponService {
166 166 public void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId) {
167 167 // 循环收回
168 168 for (Long couponId : giveCouponIds) {
169   - // couponId为空或0则跳过
  169 + // couponId 为空或 0 则跳过
170 170 if (null == couponId || couponId <= 0) {
171 171 continue;
172 172 }
... ...