欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在SpringBoot接口中正確地序列化時間字段的方法

 更新時間:2024年11月22日 08:43:10   作者:編碼的熊十二  
文章主要介紹在 Spring Boot 接口中正確序列化時間字段的方法,包括 Java 中Date和LocalDateTime類型的區(qū)別,JSON 序列化和請求參數中時間字段的處理,如時間字符串的格式配置、時間戳的使用及相關配置,還提到了在 Swagger UI 中的類型設置,需要的朋友可以參考下

在 Java 項目中處理時間序列化從來就不是容易的事。一方面要面臨多變的時間格式,年月日時分秒,毫秒,納秒,周,還有討厭的時區(qū),稍不注意就可能收獲一堆異常,另一方面,Java 又提供了 DateLocalDateTime 兩個版本的時間類型,二者分別對應著不同的序列化配置,光是弄清楚這些配置,就是一件麻煩事。但是在大多數時候,我們又不得不和這一堆配置打交道。

作為開始,讓我們來了解一下可用的配置和相應的效果。

時間字符串配置

準備一個簡單接口來展示效果。

@Slf4j
@RestController
@RequestMapping("/boom")
public class BoomController {

    @Operation(summary = "boom")
    @GetMapping
    public BoomData getBoomData() {
        return new BoomData(Clock.systemDefaultZone());
    }

    @Operation(summary = "boom")
    @PostMapping
    public BoomData postBoomData(@RequestBody BoomData boomData) {
        log.info("boomData: {}", boomData);
        return boomData;
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class BoomData {

    private Date date;
    private LocalDateTime localDateTime;
    private LocalDate localDate;
    private LocalTime localTime;

    public BoomData(Clock clock) {
        this.date = new Date(clock.millis());
        this.localDateTime = LocalDateTime.now(clock);
        this.localDate = LocalDate.now(clock);
        this.localTime = LocalTime.now(clock);
    }
}

上面涉及兩種時間類型:

  • Date 代表老版本日期類型,類似的還有 Calendar,陪著 Java 度過了漫長歲月,使用面極廣。但相對而言,設計不太跟得上時代了,比如值可變導致線程不安全,月份從 0 開始有點不正常。
  • LocalDateTime 代表 java.time 包的新版時間類型,JDK 8 中引入。新的時間類型解決老版本類型的設計缺陷,同時增加了豐富的 API 來提高易用性。

兩種類型在記錄的信息方面有一點區(qū)別:

  • Date 的時間精度為毫秒,內部實際是一個 long 類型時間戳。此外還記錄了時區(qū)信息,簡單記錄為 Date = timestamp + timezone。如果沒有提供時區(qū),默認使用系統時區(qū)。

  • LocalDateTime 時間精度為納秒,內部用 7 個整數來記錄時間:

    • int year
    • short month
    • short day
    • byte hour
    • byte minute
    • byte second
    • int nano

    可以簡單記錄為 LocalDateTime = year + month + day + hour + minute + second + nano。(實際上應該是 LocalDateTime = LocalDate + LocalTimeLocalDate = year + month + day,LocalTime = hour + minute + second + nano。)

    LocalDateTime 沒有時區(qū)信息,這也是類名中 Local 的含義,代表使用本地時區(qū)。如果需要時區(qū)信息,可以用 ZonedDateTime 類型,ZonedDateTime = LocalDateTime + tz

了解了兩個版本時間類型的區(qū)別,再看它們的序列化差異。

JSON 序列化

調用 GET 接口,得到默認的序列化結果。

{
  "date": "2024-10-10T21:07:08.781+08:00",
  "localDateTime": "2024-10-10T21:07:08.781283",
  "localDate": "2024-10-10",
  "localTime": "21:07:08.781263"
}

默認配置下,時間字段被序列化為時間字符串,但格式不盡相同。Spring Boot 使用 Jackson 進行 JSON 序列化,對不同的時間類型有不同的格式化規(guī)則:

  • Date 默認按照 ISO 標準格式化
  • LocalDateTime 也按照 ISO 標準處理,精確到微秒,少了時區(qū)
  • LocalDateLocalTime 與 LocalDateTime 處理方式相似

所謂 ISO 標準,指的是 ISO 8601 標準,一種專門處理日期時間格式的國際標準。將時間日期組合按 yyyy-MM-dd'T'HH:mm:ss.SSSXXX 格式處理,比如 2024-10-10T21:07:08.781+08:00,其中字母 T 為日期和時間分隔符,日期表示為年-月-日,時間表示為時:分:秒.毫秒。格式中的 XXX 指的是時區(qū)信息,對于東 8 區(qū),表示為 +08:00。

默認情況下,調用 POST 接口,也需要保證 body 中的 JSON 串按照 ISO 8601 的格式處理時間字段,才能正常反序列化,否則 Spring Boot 會拋出異常。當然,時間格式的要求也沒那么嚴格,可以省略時區(qū)、微秒、毫秒、秒,都能正常反序列化,但 T 不能省略,年月日時分不能省略。

在接口調用兩端統一標準時,ISO 8601 表現不壞,但是,碰到國內互聯網偏愛的 yyyy-MM-dd HH:mm:ss 格式,就會收獲一個 HttpMessageNotReadableException,JVM 會提示你 JSON parse error: Cannot deserialize value of type XXX ...

如果想要加入 yyyy-MM-dd HH:mm:ss 大家庭,最簡單的辦法是使用 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")。@JsonFormat 注解用于指定時間類型的序列格式,對 Date 類型和 LocalDateTime 類型都有效。

public class BoomData {

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date date;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime localDateTime;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate localDate;
    @JsonFormat(pattern = "HH:mm:ss")
    private LocalTime localTime;

}

此時能 GET 到滿足格式的時間字符串

{
  "date": "2024-11-20 15:15:57",
  "localDateTime": "2024-11-20 23:15:57",
  "localDate": "2024-11-20",
  "localTime": "23:15:57"
}

POST 請求也正常處理。

看樣子 @JsonFormat 效果不壞。問題是,稍微有點繁瑣,每個時間字段都要配置一遍。幸運的是,spring boot 支持全局設置 Jackson 時間序列化格式:

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss # 全局時間格式
    time-zone: GMT+8 # 指定默認時區(qū),除非時間字段已指定時區(qū),否則 JSON 序列化時都會使用此時區(qū)

更加幸運的是,@JsonFormat 優(yōu)先級比全局配置更高,讓我們可以實現某些要求特殊格式的需求。

似乎只要組合 spring.jackson.date-format 和 @JsonFormat,我們就可以無所不能了。沒有人比我更懂時間序列化!

可惜的是,spring.jackson.date-format 不支持新版時間類型。是的,在 2024 年,距離 java.time 包發(fā)布已經十年了,Spring 的序列化配置仍然不支持 LocalDateTime 類型。如果你要序列化 LocalDateTime 類型,最簡單的辦法就是使用 @JsonFormat。因為 @JsonFormat 是 Jackson 提供的注解。Spring 對此毫無作為。

發(fā)完牢騷,考慮如何全局配置 LocalDateTime 的格式化規(guī)則。方案有很多種,最簡單的就是明確地告訴 Jackson,LocalDateTime 等類型按照某某格式序列化和反序列化。

// 大概是 JacksonConfig 之類的類
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {

    return builder -> {

        // formatter
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter =  DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");

        // deserializers
        builder.deserializers(new LocalDateDeserializer(dateFormatter));
        builder.deserializers(new LocalDateTimeDeserializer(dateTimeFormatter));
        builder.deserializers(new LocalTimeDeserializer(timeFormatter));

        // serializers
        builder.serializers(new LocalDateSerializer(dateFormatter));
        builder.serializers(new LocalDateTimeSerializer(dateTimeFormatter));
        builder.serializers(new LocalTimeSerializer(timeFormatter));
    };
}

上述代碼為三種類型構建了不同的 DateTimeFormatter(java.time 包提供的格式化工具,線程安全),然后為每種類型綁定序列化器(Serializer)和反序列化器(Deserializer)。

現在 Local 系統的日期類型就跟 Date 表現一致了。

總結一下,在 JSON 序列化時:

  • 如果使用了 Date 類型,可以用 spring.jackson.date-format 和 @JsonFormat 的組合來適應不同格式化要求
  • 如果使用了 LocalDateTime 等類型,需要配置 Jackson,綁定序列化器和反序列化器,再結合 @JsonFormat 方能從心所欲

但此時還沒結束,也并非結束的開始,只是開始的結束~

請求參數

除了 JSON 序列化,還有一種場景,也會涉及時間序列化。那就是請求參數中的時間字段,最常見的就是 Controller 方法中沒有用 @RequestBody 標記的對象參數,比如 GET 請求,比如表單提交(application/x-www-form-urlencoded)的 POST 請求。

為了便于展示,在 BoomController 中添加一個新的接口方法。

@GetMapping("query")
public BoomData queryBoomData(BoomData boomData) {
    log.info("boomData: {}", boomData);
    return boomData;
}

一個比較常用的 Query 接口的寫法。試著調用一下。

GET http://localhost:8080/boom/query?localDateTime=2024-10-10T21:07:08.781283&date=2024-10-10T21:07:08.781+08:00

報錯,field 'date': rejected value [2024-10-10T21:07:08.781+08:00]。

再試試

GET http://localhost:8080/boom/query?localDateTime=2024-10-10T21:07:08.781283&date=2024-10-10 21:07:08

還是報錯,field 'date': rejected value [2024-10-10 21:07:08]。

什么格式才能不報錯?

GET http://localhost:8080/boom/query?localDateTime=2024-10-10T21:07:08.781283&date=10/10/2024 21:07:08

沒錯,要用 dd/MM/yyyy 的格式。因為請求參數不歸 JSON 序列化管,而是由 Spring MVC 處理。Spring MVC 默認的 Date 類型格式就是 dd/MM/yyyy。

要修改也簡單,@DateTimeFormat,Spring 提供,專門處理時間參數格式化。

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate localDate;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalTime localTime;

現在,正常處理請求 http://localhost:8080/boom/query?localDateTime=2024-10-10 21:07:08&date=2024-10-10 21:07:08&localDate=2024-10-10&localTime=11:09:15。

又到了尋找全局配置的時間了。

spring:
  mvc:
    format:
      date: yyyy-MM-dd HH:mm:ss # 對 Date 和 LocalDate 類型有效,LocalDate 會忽略時間部分
      time: HH:mm:ss # 對 LocalTime 和 OffsetTime 有效
      date-time: yyyy-MM-dd HH:mm:ss # LocalDateTime, OffsetDateTime, and ZonedDateTime

按需選擇即可。

總結一下,對于 GET 請求參數中的時間字段,和表單提交 POST 請求中的時間字段,可以通過 spring.mvc.format.date/time/date-time 來配置全局格式。

  • 請求中只使用了 Date 類型,只需要配置 spring.mvc.format.date
  • 如果使用了 java.time 包中的類型,需要根據類型選擇不同配置項

對于不使用全局配置的場景,用 @DateTimeFormat 指定單獨的時間格式。

一起來用時間戳吧

以上是使用時間字符串傳遞時間的情況,接下來,我們討論一下用時間戳格式。

先理解一下有關時間戳的概念:

  • GMT 時間,用來表示時區(qū),比如 GMT+8,就是指東 8 區(qū)的時間。單獨的 GMT 也可以看作 GMT+0,即 0 時區(qū)的時間,這個時區(qū)位于英國格林威治

  • UTC 時間,與 GMT 是相同的概念,也用來表示時區(qū),只不過 UTC 更精確一些。同樣,UTC+8 可以表示東 8 區(qū),單獨 UTC 表示 0 時區(qū)

  • Unix 紀 元(Unix Epoch),一個特定的時間點,1970 年 1 月 1 日 00:00:00 UTC(+0),也就是 0 時區(qū)中 1970 年元旦。這個時間點常用于計算機系統的時間起點,如同坐標軸上的 0。

指導了上述 3 個概念,時間戳的含義就容易解釋了,從 Unix 紀 元開始經過的毫秒數(或秒數,計算機常用毫秒)。把時間想象為一條長長的坐標軸,0 的位置是 Unix 紀 元,在那之后,真實世界的每一毫秒,都對應時間軸上的一個點。

時間戳用整數表示,一個長整數,具備時間字符串一樣的功能。因此,也可以用時間戳來傳遞時間信息。

如果我信誓旦旦地宣稱時間戳優(yōu)于時間字符串,肯定是十分主觀的判斷,但在接口中使用時間戳確實有一些亮晶晶的優(yōu)點。

  • 時區(qū)無關性,時間戳的值固定為 UTC+0 時區(qū),無論位于哪個時區(qū),同一時刻,同一時間戳。這樣一來,就可以僅展示時考慮時區(qū),其他時候都不需要考慮時區(qū)
  • 體積小,一個 long 值足矣,比時間字符串更簡短
  • 兼容性好,不必考慮復雜的格式化規(guī)則

一些不可忽視的缺點:

  • 可讀性差,時間戳沒有時間字符串直觀,需要一些輔助轉換工具,比如瀏覽器控制臺
  • 秒級時間戳和毫秒時間戳可能混淆,使用前要約定好

用 long 型時間戳也不需要考慮序列化問題,大多數平臺都可以妥善處理 long 類型的序列化。但有些時候,在代碼中用 Date 和 LocalDateTime 等明確的類型還是比 long 更方便。所以可能有這么一個需求:在代碼中使用時間類型,在序列化時使用時間戳。也就是在 DTO 類中用 Date,在 JSON 字符串中用 long。

和使用時間字符串類型,這個需求也分為兩種情況:

  • JSON 序列化轉換
  • 請求參數轉換

二者要分開處理。

JSON 序列化中的時間戳

Spring 提供了一個配置項,控制 Jackson 在序列化時將時間類型處理為時間戳。

spring.jackson.serialization.write-dates-as-timestamps=true

此時,GET 請求中的 date 就會變成了 "date": 1728572627475,POST 時也能正確地識別時間戳。

但是,只有 Date 才有這種優(yōu)渥的待遇,java.time 包的類型仍然面臨自己動手豐衣足食的窘境。

開啟 write-dates-as-timestamps 后,LocalDateTime 等類型會被序列化為整形數組(回憶一下 LocalDateTime 的簡單公式)。

{
  "date": 1728572627475,
  "localDateTime": [
    2024,
    10,
    10,
    23,
    3,
    47,
    475519000
  ],
  "localDate": [
    2024,
    10,
    10
  ],
  "localTime": [
    23,
    3,
    47,
    475564000
  ]
}

也不能說有問題,畢竟 LocalDateTime 精確到納秒,直接轉換為毫秒時間戳,會丟失精度??傊?,要實現和諧轉換,需要設置 Jackson。

// 仍然是 JacksonConfig 之類的什么地方
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    return builder -> {
        // deserializers
        builder.deserializers(new LocalDateDeserializer());
        builder.deserializers(new LocalDateTimeDeserializer());

        // serializers
        builder.serializers(new LocalDateSerializer());
        builder.serializers(new LocalDateTimeSerializer());
    };
}

public static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {

    /**
     * 如果沒有重寫 handledType() 方法,會報錯
     * @return LocalDateTime.class
     */
    @Override
    public Class<LocalDateTime> handledType() {
        return LocalDateTime.class;
    }

    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
        if (value != null) {
            gen.writeNumber(value.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        }
    }
}

public static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

    @Override
    public Class<?> handledType() {
        return LocalDateTime.class;
    }

    @Override
    public LocalDateTime deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
        long timestamp = parser.getValueAsLong();
        return Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDateTime();
    }
}

public static class LocalDateSerializer extends JsonSerializer<LocalDate> {

    @Override
    public Class<LocalDate> handledType() {
        return LocalDate.class;
    }

    @Override
    public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers)
            throws IOException {
        if (value != null) {
            gen.writeNumber(value.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli());
        }
    }
}

public static class LocalDateDeserializer extends JsonDeserializer<LocalDate> {

    @Override
    public Class<?> handledType() {
        return LocalDate.class;
    }

    @Override
    public LocalDate deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
        long timestamp = parser.getValueAsLong();
        return Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDate();
    }
}

這里我們進行了一些生硬的強制措施,定義了一系列 Deserializer 和 Serializer,實現了 LocalDateTime 和 long 之間的序列化規(guī)則。

沒有處理 LocalTime,因為單獨的時間轉換為時間戳不那么契合,時間戳有明確地年月日,這部分對于 LocalTime 顯得多余,而且時間通常與時區(qū)有關,處理時要更謹慎一些??梢愿鶕枨筮x擇,如果明確需要使用時間戳來表示 LocalTime,可以采用類似的方法,注冊 Deserializer 和 Serializer。

以上是在 JSON 序列化時將 Date、LocalDateTime 轉化為時間戳需要的配置:

  • 如果只使用 Date,使用 Spring 提供的配置項 spring.jackson.serialization.write-dates-as-timestamps=true 即可
  • 如果使用了 LocalDateTime,需要進行額外的配置,明確地指定 Jackson 將 LocalDateTime 轉換為時間戳

請求參數中的時間戳

在請求參數中使用時間戳復雜一些,因為不像時間字符串一樣有現成的配置,需要手動實現轉換規(guī)則。

可以利用 Converter 接口來解決這個問題。

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new LongStringToDateConverter());
        registry.addConverter(new LongStringToLocalDateTimeConverter());
        registry.addConverter(new LongStringToLocalDateConverter());
        // registry.addConverter(new LongStringToLocalTimeConverter()); // 按需
    }

    private static class LongStringToDateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String source) {
            try {
                long timestamp = Long.parseLong(source);
                return new Date(timestamp);
            } catch (NumberFormatException e) {
                return null;
            }
        }
    }

    private static class LongStringToLocalDateTimeConverter implements Converter<String, LocalDateTime> {

        @Override
        public LocalDateTime convert(String source) {
            try {
                long timestamp = Long.parseLong(source);
                return Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDateTime();
            } catch (NumberFormatException e) {
                return null;
            }
        }
    }

    private static class LongStringToLocalDateConverter implements Converter<String, LocalDate> {

        @Override
        public LocalDate convert(String source) {
            try {
                long timestamp = Long.parseLong(source);
                return Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDate();
            } catch (NumberFormatException e) {
                return null;
            }
        }
    }

    private static class LongStringToLocalTimeConverter implements Converter<String, LocalTime> {

        @Override
        public LocalTime convert(String source) {
            try {
                long timestamp = Long.parseLong(source);
                return Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalTime();
            } catch (NumberFormatException e) {
                return null;
            }
        }
    }

}

注意 Source 類型為 String 而不是 Long,因為 Spring MVC 會將所有的接口請求參數類型統一視為 String,然后調用 Converter 轉換為其他類型。有許多內置的 Converter,比如轉換為 long 類型時,就使用了內置的 StringToNumber 轉換類。我們定義的 LongStringToDateConverter 與 StringToNumber 是平級的關系。

以上是在接口參數中將 Date、LocalDateTime 轉化為時間戳需要的處理:很簡單,注冊 Converter 即可。

Swagger UI 中的類型

使用 SwaggerUI 時,默認會使用 DTO 字段類型作為請求參數類型,也就是接收時間字符串。序列化時改為時間戳后,還需要在 Swagger UI 中統一。

Java 項目有兩種集成 Swagger 的方式,Springdoc 和 Spring Fox。Springdoc 更新,對應的配置如下:

@Bean
public OpenAPI customOpenAPI() {
    // 關鍵是要調用這個靜態(tài)方法進行 replace
    SpringDocUtils.getConfig()
            .replaceWithClass(Date.class, Long.class)
            .replaceWithClass(LocalDateTime.class, Long.class)
            .replaceWithClass(LocalDate.class, Long.class);
    return new OpenAPI();
}

如果使用 Spring Fox,則需要使用另一種配置:

@Bean
public Docket createRestApi() {
    return new Docket(DocumentationType.OAS_30)
            ...
            .build()
            // 重點是這句
            .directModelSubstitute(LocalDateTime.class, Long.class);
}

此時,在 Swagger UI 頁面調試接口時,時間類型的參數就顯示為整數了。

The Only Neat Thing to Do

回顧一下,在 Spring Boot 接口中處理時間字段序列化,涉及兩個場景:

  • JSON 序列化
  • GET 請求和表單提交請求中的參數

兩種情況要分開設置。

在 Java 類型選擇方面,Spring 對 Date 類型的支持比 LocalDateTime 好,有很多內置的配置,能省去很多麻煩。

如果要使用 LocalDateTime 等類型,在 JSON 序列化時要指定時間格式,在請求參數中也要指定時間格式。前者需要手動配置,后者可以使用 Spring 提供的配置項。

如果想要用時間戳傳遞數據,也需要分別設置,在 JSON 序列化時指定序列化器和反序列化器,在請求參數中綁定對應的 Converter 實現類。此外,統一 Swagger UI 的類型體驗更佳。

以上就是在Spring Boot接口中正確地序列化時間字段的方法的詳細內容,更多關于Spring Boot序列化時間字段的資料請關注腳本之家其它相關文章!

相關文章

  • SpringBoot整合阿里云短信服務的方法

    SpringBoot整合阿里云短信服務的方法

    在實際項目中經常有發(fā)送短信的功能,今天進說一下SpringBoot整合阿里云短信服務的相關知識,新建短信微服務,編寫發(fā)送短信接口的方法文中給大家介紹的很詳細,需要的朋友參考下吧
    2021-10-10
  • 二叉排序樹的實現與基本操作

    二叉排序樹的實現與基本操作

    二叉排序樹又稱二叉查找樹。本文主要對二叉排序樹的實現與基本操作進行詳細介紹,以下代碼實現了:1、二叉樹的構建;2、二叉樹的中、前、后、層序遍歷;3、二叉樹中結點的最大距離。下面就跟著小編一起來看下吧
    2016-12-12
  • Jenkins一鍵打包部署SpringBoot應用

    Jenkins一鍵打包部署SpringBoot應用

    本文主要介紹了Jenkins一鍵打包部署SpringBoot應用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • Java回調函數實例代碼詳解

    Java回調函數實例代碼詳解

    這篇文章主要介紹了Java回調函數實例代碼詳解,需要的朋友可以參考下
    2017-10-10
  • GC算法實現垃圾優(yōu)先算法

    GC算法實現垃圾優(yōu)先算法

    為什么會存在那么多的垃圾回收算法呢?我想這個問題的答案可能是沒有任何一種內存回收算法是完美的,所以在針對不同的情景需求下,不同的內存回收算法有其獨特的優(yōu)勢,所以最后就延續(xù)了多種回收算法
    2022-01-01
  • Mybatis多個字段模糊匹配同一個值的案例

    Mybatis多個字段模糊匹配同一個值的案例

    這篇文章主要介紹了Mybatis多個字段模糊匹配同一個值的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java實現ATM系統超全面步驟解讀建議收藏

    Java實現ATM系統超全面步驟解讀建議收藏

    這篇文章主要為大家詳細介紹了用Java實現簡單ATM機功能,文中實現流程寫的非常清晰全面,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Spring實現定時任務的幾種方式總結

    Spring實現定時任務的幾種方式總結

    Spring Task 是 Spring 框架提供的一種任務調度和異步處理的解決方案,可以按照約定的時間自動執(zhí)行某個代碼邏輯它可以幫助開發(fā)者在 Spring 應用中輕松地實現定時任務、異步任務等功能,提高應用的效率和可維護性,需要的朋友可以參考下本文
    2024-07-07
  • 詳解如何使用maven生成可以執(zhí)行的jar

    詳解如何使用maven生成可以執(zhí)行的jar

    這篇文章主要介紹了詳解如何使用maven生成可以執(zhí)行的jar,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • SpringBoot操作Mongodb的實現示例

    SpringBoot操作Mongodb的實現示例

    本文主要介紹了SpringBoot操作Mongodb的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06

最新評論