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

SpringBoot中WebClient的實(shí)踐

 更新時(shí)間:2024年12月22日 11:51:50   作者:Onlooker﹒  
SpringBoot中的WebClient是一個(gè)用于與RESTful服務(wù)交互的非阻塞、響應(yīng)式HTTP客戶端,本文就來(lái)介紹一下SpringBoot中WebClient的實(shí)踐,感興趣的可以了解一下

什么是 WebClient?

在 Spring Boot 中,WebClient 是 Spring WebFlux 提供的一個(gè)非阻塞、響應(yīng)式的 HTTP 客戶端,用于與 RESTful 服務(wù)或其他 HTTP 服務(wù)交互。相比于傳統(tǒng)的 RestTemplate,WebClient 更加現(xiàn)代化,具有異步和非阻塞的特點(diǎn),適合高性能、高并發(fā)的應(yīng)用場(chǎng)景。

WebClient 的特點(diǎn)

非阻塞 I/O:適用于響應(yīng)式編程模型,能高效處理大量并發(fā)請(qǐng)求。

功能強(qiáng)大:支持同步和異步調(diào)用,處理復(fù)雜的 HTTP 請(qǐng)求和響應(yīng),包括流式數(shù)據(jù)。

靈活的配置:可自定義超時(shí)、請(qǐng)求攔截器、認(rèn)證方式等。

響應(yīng)式編程支持:返回 Mono 或 Flux,與 Spring WebFlux 的響應(yīng)式編程模型無(wú)縫集成。

引入依賴

在使用 WebClient 之前,需要確保 Spring Boot 項(xiàng)目已包含相關(guān)依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

配置及使用 WebClient

現(xiàn)在有以下服務(wù)

  • service1服務(wù):http://localhost:8081/
  • service2服務(wù):http://localhost:8082/
  • common服務(wù):http://localhost:8079/

創(chuàng)建 WebClientConfig 配置類,為 service1 和 service2 配置獨(dú)立的 WebClient。

package com.example.common.config;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;

/**
 * 配置 WebClient,支持基礎(chǔ)功能(獨(dú)立 WebClient 實(shí)例)和高級(jí)特性(超時(shí)、攔截器、內(nèi)存限制)。
 */
@Configuration
public class WebClientConfig {

    /**
     * 配置 WebClient,用于調(diào)用 service1(http://localhost:8081)
     *
     * @param builder WebClient.Builder 實(shí)例
     * @return 針對(duì) service1 的 WebClient 實(shí)例
     */
    @Bean(name = "service1WebClient")
    public WebClient service1WebClient(WebClient.Builder builder) {
        return builder
                .baseUrl("http://localhost:8081") // 配置 service1 的基本 URL
                .defaultHeader("Content-Type", "application/json") // 設(shè)置默認(rèn)請(qǐng)求頭
                .exchangeStrategies(
                        ExchangeStrategies.builder()
                                .codecs(configurer -> configurer
                                        .defaultCodecs()
                                        .maxInMemorySize(16 * 1024 * 1024)) // 設(shè)置最大內(nèi)存限制為 16MB
                                .build())
                .filter(logRequest()) // 添加請(qǐng)求日志攔截器
                .filter(logResponse()) // 添加響應(yīng)日志攔截器
                .build();
    }

    /**
     * 配置 WebClient,用于調(diào)用 service2(http://localhost:8082)
     *
     * @param builder WebClient.Builder 實(shí)例
     * @return 針對(duì) service2 的 WebClient 實(shí)例
     */
    @Bean(name = "service2WebClient")
    public WebClient service2WebClient(WebClient.Builder builder) {
        return builder
                .baseUrl("http://localhost:8082") // 配置 service2 的基本 URL
                .defaultHeader("Content-Type", "application/json") // 設(shè)置默認(rèn)請(qǐng)求頭
                .filter(logRequest()) // 添加請(qǐng)求日志攔截器
                .filter(logResponse()) // 添加響應(yīng)日志攔截器
                .build();
    }

    /**
     * 提供全局的 WebClient.Builder 配置,支持超時(shí)和高級(jí)功能。
     *
     * @return 配置好的 WebClient.Builder
     */
    @Bean
    public WebClient.Builder webClientBuilder() {
        // 配置 TCP 客戶端,設(shè)置連接超時(shí)、讀超時(shí)和寫超時(shí)
        TcpClient tcpClient = TcpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí) 5秒
                .doOnConnected(connection ->
                        connection.addHandlerLast(new ReadTimeoutHandler(5)) // 讀超時(shí) 5秒
                                  .addHandlerLast(new WriteTimeoutHandler(5))); // 寫超時(shí) 5秒

        // 使用配置的 TcpClient 創(chuàng)建 HttpClient
        HttpClient httpClient = HttpClient.from(tcpClient);

        // 創(chuàng)建 WebClient.Builder 并配置 HttpClient 和攔截器
        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient)) // 配置 HttpClient
                .filter(logRequest()) // 請(qǐng)求日志攔截器
                .filter(logResponse()); // 響應(yīng)日志攔截器
    }

    /**
     * 請(qǐng)求日志攔截器:記錄請(qǐng)求的詳細(xì)信息(方法和 URL)
     *
     * @return ExchangeFilterFunction 攔截器
     */
    private ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(request -> {
            System.out.println("Request: " + request.method() + " " + request.url());
            return Mono.just(request);
        });
    }

    /**
     * 響應(yīng)日志攔截器:記錄響應(yīng)的狀態(tài)碼
     *
     * @return ExchangeFilterFunction 攔截器
     */
    private ExchangeFilterFunction logResponse() {
        return ExchangeFilterFunction.ofResponseProcessor(response -> {
            System.out.println("Response status: " + response.statusCode());
            return Mono.just(response);
        });
    }
}

service1相應(yīng)的接口

package cloud.service1.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * Service1 的控制器類,用于處理與API相關(guān)的請(qǐng)求.
 * 該類被Spring框架管理,作為處理HTTP請(qǐng)求的一部分.
 */
@RestController
@RequestMapping("/api/service1")
public class Service1Controller {

    /**
     * 獲取Service1的數(shù)據(jù)信息.
     * 
     * @return 包含服務(wù)信息的映射,包括服務(wù)名稱和問(wèn)候消息.
     */
    @GetMapping("/data")
    public Map<String, String> getData() {
        // 返回一個(gè)不可變的映射,包含服務(wù)名稱和問(wèn)候消息
        return Map.of("service", "service1", "message", "Hello from Service1");
    }
}

service2相應(yīng)的接口

package cloud.service2.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * Service2的控制器類,用于處理與Service2相關(guān)的HTTP請(qǐng)求.
 * 該類被Spring框架管理,作為處理RESTful請(qǐng)求的控制器.
 */
@RestController
@RequestMapping("/api/service2")
public class Service2Controller {

    /**
     * 處理GET請(qǐng)求到/api/service2/info,返回Service2的信息.
     * 
     * @return 包含服務(wù)信息的Map,包括服務(wù)名稱和歡迎消息.
     */
    @GetMapping("/info")
    public Map<String, String> getInfo() {
        return Map.of("service", "service2", "message", "Hello from Service2");
    }
}

服務(wù)調(diào)用實(shí)現(xiàn)

package com.example.common.service;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * CommonService 類提供了對(duì)其他服務(wù)進(jìn)行調(diào)用的方法
 * 它通過(guò) WebClient 實(shí)例與 service1 和 service2 進(jìn)行通信
 */
@Service
public class CommonService {

    // 用于與 service1 通信的 WebClient 實(shí)例
    private final WebClient service1WebClient;
    // 用于與 service2 通信的 WebClient 實(shí)例
    private final WebClient service2WebClient;

    /**
     * 構(gòu)造函數(shù)注入兩個(gè) WebClient 實(shí)例
     *
     * @param service1WebClient 用于 service1 的 WebClient
     * @param service2WebClient 用于 service2 的 WebClient
     */
    public CommonService(
            @Qualifier("service1WebClient") WebClient service1WebClient,
            @Qualifier("service2WebClient") WebClient service2WebClient) {
        this.service1WebClient = service1WebClient;
        this.service2WebClient = service2WebClient;
    }

    /**
     * 調(diào)用 service1 的接口
     *
     * @return 來(lái)自 service1 的數(shù)據(jù)
     */
    public Mono<String> callService1() {
        // 通過(guò) service1WebClient 調(diào)用 service1 的 API,并處理可能的錯(cuò)誤
        return service1WebClient.get()
                .uri("/api/service1/data")
                .retrieve()
                .bodyToMono(String.class)
                .onErrorResume(e -> {
                    // 錯(cuò)誤處理:打印錯(cuò)誤信息并返回錯(cuò)誤提示
                    System.err.println("Error calling service1: " + e.getMessage());
                    return Mono.just("Error calling service1");
                });
    }

    /**
     * 調(diào)用 service2 的接口
     *
     * @return 來(lái)自 service2 的數(shù)據(jù)
     */
    public Mono<String> callService2() {
        // 通過(guò) service2WebClient 調(diào)用 service2 的 API,并處理可能的錯(cuò)誤
        return service2WebClient.get()
                .uri("/api/service2/info")
                .retrieve()
                .bodyToMono(String.class)
                .onErrorResume(e -> {
                    // 錯(cuò)誤處理:打印錯(cuò)誤信息并返回錯(cuò)誤提示
                    System.err.println("Error calling service2: " + e.getMessage());
                    return Mono.just("Error calling service2");
                });
    }
}
package com.example.common.controller;

import com.example.common.service.CommonService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * 通用控制器類,處理與通用服務(wù)相關(guān)的API請(qǐng)求
 */
@RestController
@RequestMapping("/api/common")
public class CommonController {

    // 注入通用服務(wù)接口,用于調(diào)用具體的服務(wù)方法
    private final CommonService commonService;

    /**
     * 構(gòu)造函數(shù)注入CommonService實(shí)例
     *
     * @param commonService 通用服務(wù)接口實(shí)例
     */
    public CommonController(CommonService commonService) {
        this.commonService = commonService;
    }

    /**
     * 調(diào)用 service1 的接口
     *
     * @return service1 的響應(yīng)數(shù)據(jù)
     */
    @GetMapping("/service1")
    public Mono<String> getService1Data() {
        return commonService.callService1();
    }

    /**
     * 調(diào)用 service2 的接口
     *
     * @return service2 的響應(yīng)數(shù)據(jù)
     */
    @GetMapping("/service2")
    public Mono<String> getService2Info() {
        return commonService.callService2();
    }
}

測(cè)試接口

優(yōu)化實(shí)踐

將上述代碼進(jìn)一步優(yōu)化和整合以確保代碼可維護(hù)性和高效性。

package com.example.common.config;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;

/**
 * 配置 WebClient 的各類設(shè)置和日志記錄
 */
@Configuration
public class WebClientConfig {

    /**
     * 全局 WebClient.Builder 配置
     *
     * @return 配置好的 WebClient.Builder
     */
    @Bean
    public WebClient.Builder webClientBuilder() {
        // 配置 TCP 客戶端的連接、讀取、寫入超時(shí)時(shí)間
        TcpClient tcpClient = TcpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí)
                .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(5)) // 讀超時(shí)
                        .addHandlerLast(new WriteTimeoutHandler(5))); // 寫超時(shí)

        // 將 TCP 客戶端配置應(yīng)用到 HTTP 客戶端
        HttpClient httpClient = HttpClient.from(tcpClient);

        // 配置 WebClient 構(gòu)建器,包括 HTTP 連接器、交換策略、請(qǐng)求和響應(yīng)日志
        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .exchangeStrategies(ExchangeStrategies.builder()
                        .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024)) // 內(nèi)存限制
                        .build())
                .filter(logRequest())  // 請(qǐng)求日志
                .filter(logResponse()); // 響應(yīng)日志
    }

    /**
     * 針對(duì) service1 的 WebClient 配置
     *
     * @param builder 全局配置的 WebClient.Builder
     * @return 配置好的 WebClient 實(shí)例
     */
    @Bean(name = "service1WebClient")
    public WebClient service1WebClient(WebClient.Builder builder) {
        // 為 service1 配置特定的 base URL 和默認(rèn)頭部
        return builder
                .baseUrl("http://localhost:8081")
                .defaultHeader("Content-Type", "application/json")
                .build();
    }

    /**
     * 針對(duì) service2 的 WebClient 配置
     *
     * @param builder 全局配置的 WebClient.Builder
     * @return 配置好的 WebClient 實(shí)例
     */
    @Bean(name = "service2WebClient")
    public WebClient service2WebClient(WebClient.Builder builder) {
        // 為 service2 配置特定的 base URL 和默認(rèn)頭部
        return builder
                .baseUrl("http://localhost:8082")
                .defaultHeader("Content-Type", "application/json")
                .build();
    }

    /**
     * 請(qǐng)求日志攔截器
     *
     * @return 記錄請(qǐng)求日志的 ExchangeFilterFunction
     */
    private ExchangeFilterFunction logRequest() {
        // 攔截請(qǐng)求并打印請(qǐng)求方法和URL
        return ExchangeFilterFunction.ofRequestProcessor(request -> {
            System.out.println("Request: " + request.method() + " " + request.url());
            return Mono.just(request);
        });
    }

    /**
     * 響應(yīng)日志攔截器
     *
     * @return 記錄響應(yīng)日志的 ExchangeFilterFunction
     */
    private ExchangeFilterFunction logResponse() {
        // 攔截響應(yīng)并打印響應(yīng)狀態(tài)碼
        return ExchangeFilterFunction.ofResponseProcessor(response -> {
            System.out.println("Response status: " + response.statusCode());
            return Mono.just(response);
        });
    }
}
package com.example.common.service;

import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * CommonService 類提供了調(diào)用兩個(gè)不同服務(wù)的公共方法,并合并其結(jié)果
 */
@Service
public class CommonService {

    // service1 的 WebClient 實(shí)例
    private final WebClient service1WebClient;
    // service2 的 WebClient 實(shí)例
    private final WebClient service2WebClient;

    /**
     * 構(gòu)造函數(shù)注入 WebClient 實(shí)例
     *
     * @param service1WebClient service1 的 WebClient
     * @param service2WebClient service2 的 WebClient
     */
    public CommonService(WebClient service1WebClient, WebClient service2WebClient) {
        this.service1WebClient = service1WebClient;
        this.service2WebClient = service2WebClient;
    }

    /**
     * 異步調(diào)用 service1 和 service2,并返回合并結(jié)果(JSON 格式)
     *
     * @return 包含兩個(gè)服務(wù)響應(yīng)的 Mono 對(duì)象
     */
    public Mono<Map<String, Map<String, String>>> callServicesAsync() {
        // 調(diào)用 service1,返回 Map 響應(yīng)
        Mono<Map<String, String>> service1Response = service1WebClient.get()
                // 設(shè)置請(qǐng)求的URI
               .uri("/api/service1/data")
                // 檢索響應(yīng)
               .retrieve()
                // 處理錯(cuò)誤狀態(tài)
               .onStatus(
                        // 檢查狀態(tài)是否為4xx或5xx
                        status -> status.is4xxClientError() || status.is5xxServerError(),
                        // 如果是,創(chuàng)建一個(gè)運(yùn)行時(shí)異常
                        response -> Mono.error(new RuntimeException("Service1 Error: " + response.statusCode()))
                )
                // 將響應(yīng)體轉(zhuǎn)換為Mono<Map<String, String>>
               .bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {})
                // 處理錯(cuò)誤
               .onErrorResume(e -> {
                    // 打印錯(cuò)誤信息
                    System.err.println("Error calling service1: " + e.getMessage());
                    // 返回一個(gè)包含錯(cuò)誤信息的Map
                    return Mono.just(Map.of("error", "Fallback response for service1"));
                });

        // 調(diào)用 service2,返回 Map 響應(yīng)
        Mono<Map<String, String>> service2Response = service2WebClient.get()
                // 設(shè)置請(qǐng)求的URI
               .uri("/api/service2/info")
                // 檢索響應(yīng)
               .retrieve()
                // 處理錯(cuò)誤狀態(tài)
               .onStatus(
                        // 檢查狀態(tài)是否為4xx或5xx
                        status -> status.is4xxClientError() || status.is5xxServerError(),
                        // 如果是,創(chuàng)建一個(gè)運(yùn)行時(shí)異常
                        response -> Mono.error(new RuntimeException("Service2 Error: " + response.statusCode()))
                )
                // 將響應(yīng)體轉(zhuǎn)換為Mono<Map<String, String>>
               .bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {})
                // 處理錯(cuò)誤
               .onErrorResume(e -> {
                    // 打印錯(cuò)誤信息
                    System.err.println("Error calling service2: " + e.getMessage());
                    // 返回一個(gè)包含錯(cuò)誤信息的Map
                    return Mono.just(Map.of("error", "Fallback response for service2"));
                });

        // 合并兩個(gè)響應(yīng)
        return Mono.zip(service1Response, service2Response, (response1, response2) -> Map.of(
                "service1", response1,
                "service2", response2
        ))
        // 處理合并過(guò)程中的錯(cuò)誤
       .onErrorResume(e -> {
            // 打印錯(cuò)誤信息
            System.err.println("Error combining responses: " + e.getMessage());
            // 返回一個(gè)包含錯(cuò)誤信息的Map
            return Mono.just(Map.of(
                    "error", Map.of(
                            "status", "error",
                            "message", e.getMessage() // 捕獲異常并輸出信息
                    )
            ));
        });
    }
}
package com.example.common.controller;

import com.example.common.service.CommonService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.util.Map;

@RestController
@RequestMapping("/api/common")
public class CommonController {

    private final CommonService commonService;

    public CommonController(CommonService commonService) {
        this.commonService = commonService;
    }

    /**
     * 提供異步調(diào)用的 REST 接口,返回 JSON 格式的數(shù)據(jù)
     */
    @GetMapping("/service")
    public Mono<Map<String, Map<String, String>>> getServicesData() {
        System.out.println("Received request for combined service data");
        return commonService.callServicesAsync()
                .doOnSuccess(response -> System.out.println("Successfully retrieved data: " + response))
                .doOnError(error -> System.err.println("Error occurred while fetching service data: " + error.getMessage()));
    }
}

測(cè)試接口 

結(jié)語(yǔ) 

WebClient 是一個(gè)功能強(qiáng)大且靈活的非阻塞 HTTP 客戶端,特別適合在高并發(fā)和響應(yīng)式編程場(chǎng)景下使用,是替代傳統(tǒng) RestTemplate 的優(yōu)秀選擇。在實(shí)際項(xiàng)目中,通過(guò)合理配置(如超時(shí)、連接池)和優(yōu)化(如負(fù)載均衡、重試機(jī)制),可以顯著提高服務(wù)間通信的效率和可靠性,降低延遲和資源消耗。

同時(shí),結(jié)合 Spring WebFlux 提供的響應(yīng)式編程支持,WebClient 能夠更好地應(yīng)對(duì)微服務(wù)架構(gòu)中復(fù)雜的通信需求,成為開(kāi)發(fā)現(xiàn)代分布式系統(tǒng)的重要工具。

到此這篇關(guān)于SpringBoot中WebClient的實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot WebClient內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud?hystrix斷路器與全局解耦全面介紹

    SpringCloud?hystrix斷路器與全局解耦全面介紹

    什么是服務(wù)降級(jí)?當(dāng)服務(wù)器壓力劇增的情況下,根據(jù)實(shí)際業(yè)務(wù)情況及流量,對(duì)一些服務(wù)和頁(yè)面有策略的不處理或換種簡(jiǎn)單的方式處理,從而釋放服務(wù)器資源以保證核心交易正常運(yùn)作或高效運(yùn)作
    2022-10-10
  • Java基礎(chǔ)學(xué)習(xí)之構(gòu)造方法詳解

    Java基礎(chǔ)學(xué)習(xí)之構(gòu)造方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java基礎(chǔ)學(xué)習(xí)中構(gòu)造方法的概述及注意事項(xiàng),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-08-08
  • MyBatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的示例代碼

    MyBatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的示例代碼

    這篇文章主要介紹了MyBatis-Plus實(shí)現(xiàn)多數(shù)據(jù)源的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • java中TCP實(shí)現(xiàn)回顯服務(wù)器及客戶端

    java中TCP實(shí)現(xiàn)回顯服務(wù)器及客戶端

    本文主要介紹了java中TCP實(shí)現(xiàn)回顯服務(wù)器及客戶端,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • java實(shí)現(xiàn)雷霆戰(zhàn)機(jī)

    java實(shí)現(xiàn)雷霆戰(zhàn)機(jī)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)雷霆戰(zhàn)機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 一篇文章帶你了解Java SpringBoot Nacos

    一篇文章帶你了解Java SpringBoot Nacos

    這篇文章主要介紹了SpringBoot使用Nacos配置中心的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • win11?idea?shift+F6快捷鍵失效問(wèn)題解決方案

    win11?idea?shift+F6快捷鍵失效問(wèn)題解決方案

    這篇文章主要介紹了win11?idea?shift+F6快捷鍵失效問(wèn)題,本文給大家分享最新解決方案,需要的朋友可以參考下
    2023-08-08
  • 使用spring的IOC解決程序耦合的方法

    使用spring的IOC解決程序耦合的方法

    這篇文章主要介紹了使用spring的IOC解決程序耦合的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn)

    SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn)

    日志記錄是不可或缺的一部分,本文主要介紹了SpringBoot日志配置SLF4J和Logback的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • SpringBoot項(xiàng)目如何把接口參數(shù)中的空白值替換為null值(推薦)

    SpringBoot項(xiàng)目如何把接口參數(shù)中的空白值替換為null值(推薦)

    這篇文章主要介紹了SpringBoot項(xiàng)目如何把接口參數(shù)中的空白值替換為null值(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01

最新評(píng)論