国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringCore完整學習教程6,入門級別

這篇具有很好參考價值的文章主要介紹了SpringCore完整學習教程6,入門級別。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本章從第7章開始:

7. Task Execution and Scheduling

在上下文中沒有Executor bean的情況下,Spring Boot會自動配置一個ThreadPoolTaskExecutor,它具有合理的默認值,可以自動關聯(lián)到異步任務執(zhí)行(@EnableAsync)和Spring MVC異步請求處理。

如果你在上下文中定義了自定義Executor,常規(guī)任務執(zhí)行(即@EnableAsync)將透明地使用它,但不會配置Spring MVC支持,因為它需要AsyncTaskExecutor實現(xiàn)(名為applicationTaskExecutor)。根據(jù)您的目標安排,您可以將Executor更改為ThreadPoolTaskExecutor或定義ThreadPoolTaskExecutor和AsyncConfigurer封裝您的自定義Executor。

自動配置的TaskExecutorBuilder允許您輕松地創(chuàng)建實例來重現(xiàn)默認情況下自動配置所做的事情。

線程池使用8個核心線程,這些線程可以根據(jù)負載增長和收縮。這些默認設置可以使用spring.task.execution命名空間進行微調,如下例所示:

spring.task.execution.pool.max-size=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s

測試:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @Async("taskExecutor")
    public void test() {
        // do something
    }
}

在這個測試代碼中,@Async注解表示這個方法是異步執(zhí)行的,"taskExecutor"表示使用的線程池的名稱。在使用時,只需要注入TestService并調用test()方法即可。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
@ConfigurationPropertiesScan(basePackages = "com.example.demo.demos")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(DemoApplication.class);
        application.run(args);
    }

}

開啟一下Spring的異步特性的。

這會將線程池更改為使用有界隊列,以便當隊列滿時(100個任務),線程池增加到最多16個線程。當線程空閑10秒(而不是默認的60秒)時回收它們,池的收縮會更加激進。

如果需要與計劃任務執(zhí)行相關聯(lián)(例如使用@ enablesscheduling), ThreadPoolTaskScheduler也可以自動配置。線程池默認使用一個線程,可以使用spring.task.scheduling命名空間對其設置進行微調,如下例所示:

spring.task.scheduling.thread-name-prefix=scheduling-
spring.task.scheduling.pool.size=2

如果需要創(chuàng)建自定義執(zhí)行器或調度器,那么TaskExecutorBuilder bean和TaskSchedulerBuilder bean都可以在上下文中使用。

8. Testing

Spring Boot提供了許多實用工具和注釋,可以在測試應用程序時提供幫助。測試支持由兩個模塊提供:spring-boot-test包含核心項,spring-boot-test-autoconfigure支持測試的自動配置。
大多數(shù)開發(fā)人員使用Spring - Boot - Starter -test“Starter”,它導入Spring - Boot測試模塊以及JUnit Jupiter、AssertJ、Hamcrest和許多其他有用的庫。

如果您有使用JUnit 4的測試,那么可以使用JUnit 5的老式引擎來運行它們。要使用復古引擎,需要在junit-vintage-engine上添加一個依賴項,如下例所示:

<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>

8.1. Test Scope Dependencies

spring-boot-starter-test“Starter”(在測試范圍內(nèi))包含以下提供的庫:

  • JUnit 5:單元測試Java應用程序的事實標準

  • Spring Test?& Spring Boot Test: 對Spring Boot應用程序的實用程序和集成測試支持。

  • AssertJ: 一個流暢的斷言庫

  • Hamcrest: 匹配器對象庫(也稱為約束或謂詞)。

  • Mockito: 一個Java模擬框架。

  • JSONassert: 一個JSON斷言庫。

  • JsonPath: 用于JSON的XPath。

我們通常發(fā)現(xiàn)這些公共庫在編寫測試時很有用。如果這些庫不能滿足您的需求,您可以添加自己的額外測試依賴項。

8.2. Testing Spring Applications

依賴注入的一個主要優(yōu)點是,它可以使代碼更容易進行單元測試。您可以通過使用new操作符實例化對象,甚至不需要使用Spring。您還可以使用模擬對象來代替真正的依賴項。

通常,您需要超越單元測試并開始集成測試(使用Spring ApplicationContext)。能夠在不需要部署應用程序或連接到其他基礎設施的情況下執(zhí)行集成測試是很有用的。

Spring框架包括一個專門用于這種集成測試的測試模塊。你可以直接聲明一個依賴于org.springframework:spring-test或使用spring-boot-starter-test“Starter”來傳遞地拉入它。

8.3. Testing Spring Boot Applications

Spring Boot應用程序是一個Spring ApplicationContext,所以除了通常使用普通Spring上下文所做的測試之外,不需要做任何特別的事情來測試它。

默認情況下,只有在使用SpringApplication創(chuàng)建時,Spring Boot的外部屬性、日志記錄和其他特性才會安裝在上下文中。

SpringBoot提供了一個@SpringBootTest注釋,當您需要SpringBoot特性時,它可以作為標準Spring -test @ContextConfiguration注釋的替代。注釋的工作原理是通過SpringApplication創(chuàng)建測試中使用的ApplicationContext。除了@SpringBootTest之外,還提供了許多其他注釋,用于測試應用程序的更具體的片段。

如果您使用的是JUnit 4,不要忘記在測試中添加@RunWith(sprinrunner .class),否則注釋將被忽略。如果你使用的是JUnit 5,就不需要添加@ extendwith (SpringExtension.class)作為@ springboottest和其他@…Test注釋已經(jīng)用它進行了注釋

默認情況下,@SpringBootTest不會啟動服務器。你可以使用@SpringBootTest的webEnvironment屬性來進一步優(yōu)化測試的運行方式:

MOCK(默認):加載web ApplicationContext并提供模擬web環(huán)境。使用此注釋時,嵌入式服務器不會啟動。如果在你的類路徑上沒有一個web環(huán)境可用,這種模式就會透明地退回到創(chuàng)建一個常規(guī)的非web ApplicationContext。它可以與@AutoConfigureMockMvc或@AutoConfigureWebTestClient一起使用,用于基于模擬的web應用程序測試。

RANDOM_PORT:加載WebServerApplicationContext并提供一個真實的web環(huán)境。嵌入式服務器啟動并在隨機端口上偵聽。

DEFINED_PORT:加載WebServerApplicationContext并提供一個真實的web環(huán)境。嵌入式服務器在一個定義的端口(來自application.properties)上啟動并偵聽,或者在默認端口8080上偵聽。

NONE:通過使用SpringApplication加載ApplicationContext,但不提供任何web環(huán)境(mock或其他)。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
class DemoApplicationTests {

或者:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {

如果您的測試是@Transactional的,默認情況下,它會在每個測試方法結束時回滾事務。然而,使用RANDOM_PORT或DEFINED_PORT的這種安排隱式地提供了一個真正的servlet環(huán)境,HTTP客戶端和服務器在單獨的線程中運行,因此在單獨的事務中運行。在這種情況下,服務器上發(fā)起的任何事務都不會回滾。

@SpringBootTest with webEnvironment = webEnvironment。如果應用程序為管理服務器使用不同的端口,RANDOM_PORT還將在一個單獨的隨機端口上啟動管理服務器。

8.3.1. Detecting Web Application Type

如果Spring MVC可用,則配置一個常規(guī)的基于MVC的應用程序上下文。如果你只有Spring WebFlux,我們會檢測并配置一個基于WebFlux的應用上下文。
如果兩者都存在,則優(yōu)先考慮Spring MVC。如果你想在這種情況下測試一個響應式web應用程序,你必須設置spring.main.web-application-type屬性:

import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(properties = "spring.main.web-application-type=reactive")
class MyWebFluxTests {

    // ...

}

8.3.2. Detecting Test Configuration

如果您熟悉Spring測試框架,您可能習慣于使用@ContextConfiguration(classes=…)來指定加載哪個Spring @Configuration?;蛘?,您可能經(jīng)常在測試中使用嵌套的@Configuration類。

在測試Spring Boot應用程序時,通常不需要這樣做。Spring Boot的@*Test注釋在您沒有顯式定義主配置時自動搜索主配置。

搜索算法從包含測試的包開始查找,直到找到帶有@SpringBootApplication或@SpringBootConfiguration注釋的類。只要以一種合理的方式組織代碼,通常就能找到主配置。

如果您使用測試注釋來測試應用程序中更具體的部分,那么您應該避免在主方法的應用程序類中添加特定于特定區(qū)域的配置設置。
@SpringBootApplication的底層組件掃描配置定義了用于確保切片按預期工作的排除過濾器。如果你在@ springbootapplication注釋的類上使用顯式的@ComponentScan指令,請注意這些過濾器將被禁用。如果您正在使用切片,則應該重新定義它們。

如果你想定制主配置,你可以使用嵌套的@TestConfiguration類。與嵌套的@Configuration類不同,嵌套的@TestConfiguration類是用來代替應用程序的主要配置的,而嵌套的@TestConfiguration類是用來代替應用程序的主要配置的。

Spring的測試框架在測試之間緩存應用程序上下文。因此,只要您的測試共享相同的配置(無論如何發(fā)現(xiàn)它),加載上下文的潛在耗時過程只會發(fā)生一次。

8.3.3. Excluding Test Configuration

如果您的應用程序使用組件掃描(例如,如果您使用@SpringBootApplication或@ComponentScan),您可能會發(fā)現(xiàn)僅為特定測試創(chuàng)建的頂級配置類意外地在各處被拾取。
正如我們前面看到的,@TestConfiguration可以在測試的內(nèi)部類上使用,以定制主配置。當放置在頂級類上時,@TestConfiguration表示src/test/java中的類不應該被掃描。然后你可以在需要的地方顯式導入這個類,如下面的例子所示:

import org.junit.jupiter.api.Test;

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;

@SpringBootTest
@Import(MyTestsConfiguration.class)
class MyTests {

    @Test
    void exampleTest() {
        // ...
    }

}

如果你直接使用@ComponentScan(也就是說,不是通過@SpringBootApplication),你需要注冊TypeExcludeFilter。

8.3.4. Using Application Arguments

如果應用程序需要參數(shù),可以讓@SpringBootTest使用args屬性注入?yún)?shù)。

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.test.context.SpringBootTest;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(args = "--app.test=one")
class MyApplicationArgumentTests {

    @Test
    void applicationArgumentsPopulated(@Autowired ApplicationArguments args) {
        assertThat(args.getOptionNames()).containsOnly("app.test");
        assertThat(args.getOptionValues("app.test")).containsOnly("one");
    }

}

8.3.5. Testing With a Mock Environment

默認情況下,@SpringBootTest不會啟動服務器,而是為測試web端點設置一個模擬環(huán)境。
使用Spring MVC,我們可以使用MockMvc或WebTestClient查詢我們的web端點,如下面的例子所示:

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
class MyMockMvcTests {

    @Test
    void testWithMockMvc(@Autowired MockMvc mvc) throws Exception {
        mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
    }

    // If Spring WebFlux is on the classpath, you can drive MVC tests with a WebTestClient
    @Test
    void testWithWebTestClient(@Autowired WebTestClient webClient) {
        webClient
                .get().uri("/")
                .exchange()
                .expectStatus().isOk()
                .expectBody(String.class).isEqualTo("Hello World");
    }

}

@AutoConfigureMockMvc它可以自動配置MockMvc并將其注入到測試類中。在使用Spring Boot進行單元測試時,我們可以使用它來模擬HTTP請求和響應,以便測試我們的控制器是否按預期工作。

如果你只想關注web層,而不想啟動一個完整的ApplicationContext,可以考慮使用@WebMvcTest。

使用Spring WebFlux端點,你可以使用WebTestClient,如下例所示:

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest
@AutoConfigureWebTestClient
class MyMockWebTestClientTests {

    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient
            .get().uri("/")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Hello World");
    }

}

在模擬環(huán)境中進行測試通常比在完整的servlet容器中運行要快。然而,由于mock發(fā)生在Spring MVC層,依賴于低級servlet容器行為的代碼不能直接用MockMvc進行測試。
例如,Spring Boot的錯誤處理基于servlet容器提供的“錯誤頁”支持。這意味著,雖然您可以按照預期測試MVC層拋出和處理異常,但您不能直接測試是否呈現(xiàn)了特定的自定義錯誤頁面。如果您需要測試這些較低級別的關注點,您可以啟動一個完全運行的服務器,如下一節(jié)所述。

8.3.6. Testing With a Running Server

如果您需要啟動一個完整運行的服務器,我們建議您使用隨機端口。如果您使用@SpringBootTest(webEnvironment= webEnvironment . random_port),那么每次測試運行時都會隨機選擇一個可用的端口。

可以使用@LocalServerPort注釋將實際使用的端口注入到測試中。為方便起見,需要對已啟動服務器進行REST調用的測試可以另外@Autowire一個WebTestClient,它解析到正在運行的服務器的相對鏈接,并附帶一個專用的API來驗證響應,如下例所示:

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.web.reactive.server.WebTestClient;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortWebTestClientTests {

    @Test
    void exampleTest(@Autowired WebTestClient webClient) {
        webClient
            .get().uri("/")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class).isEqualTo("Hello World");
    }

}

WebTestClient既可以用于活動服務器,也可以用于模擬環(huán)境。

這個設置需要類路徑上的spring-webflux。如果你不能或不打算添加webflux, Spring Boot也提供了一個TestRestTemplate工具:

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MyRandomPortTestRestTemplateTests {

    @Test
    void exampleTest(@Autowired TestRestTemplate restTemplate) {
        String body = restTemplate.getForObject("/", String.class);
        assertThat(body).isEqualTo("Hello World");
    }

}

記得點關注文章來源地址http://www.zghlxwxcb.cn/news/detail-714026.html

到了這里,關于SpringCore完整學習教程6,入門級別的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 一個簡單的增刪改查Spring boot項目教程(完整過程,附代碼)(從搭建數(shù)據(jù)庫到實現(xiàn)增刪改查功能),Springboot學習,Springboot項目,

    一個簡單的增刪改查Spring boot項目教程(完整過程,附代碼)(從搭建數(shù)據(jù)庫到實現(xiàn)增刪改查功能),Springboot學習,Springboot項目,

    這里將會介紹怎么去搭建一個簡單增刪改查的Springboot項目,認真看完我相信你一定能夠學會,并且附有完整代碼; 首先要進行增刪改查肯定是要有供操作的數(shù)據(jù)庫; 這里我是用的SQLyog來搭建的,隨便用什么都可以,只要能確保給項目一個配套的數(shù)據(jù)庫就行; 打開IDEA,創(chuàng)建

    2024年02月15日
    瀏覽(98)
  • 【Java基礎教程】Java學習路線攻略導圖——史詩級別的細粒度歸納 ~

    【Java基礎教程】Java學習路線攻略導圖——史詩級別的細粒度歸納 ~

    ???? 各位讀者朋友大家好!得益于各位朋友的支持和關注,我的專欄《Java基礎教程》 至今已經(jīng)更新完畢,我們一起探索了Java語言的許多核心概念和重要特性。在過去的文章中,我們 一共涉及了入門知識介紹、編程基礎概念、面向對象OOP、包及訪問控制權限、異常處理篇、

    2024年02月14日
    瀏覽(51)
  • 【Java基礎教程】Java學習路線攻略導圖——史詩級別的細粒度歸納,持續(xù)更新中 ~

    【Java基礎教程】Java學習路線攻略導圖——史詩級別的細粒度歸納,持續(xù)更新中 ~

    ???? 各位讀者朋友大家好!得益于各位朋友的支持和關注,我的專欄《Java基礎教程》 至今已經(jīng)更新完畢,我們一起探索了Java語言的許多核心概念和重要特性。在過去的文章中,我們 一共涉及了入門知識介紹、編程基礎概念、面向對象OOP、包及訪問控制權限、異常處理篇、

    2024年02月16日
    瀏覽(64)
  • 完整教程:深度學習環(huán)境配置(GPU條件&pytorch)

    完整教程:深度學習環(huán)境配置(GPU條件&pytorch)

    如果是python小白,強烈推薦B站小土堆的視頻,講得很清晰(但需要花些時間),地址如下: 最詳細的 Windows 下 PyTorch 入門深度學習環(huán)境安裝與配置 CPU GPU 版 如果有些基礎,跟著往下看就行。 配置 作用 Anaconda 靈活切換python運行環(huán)境、高效使用python包 GPU 軟硬件:硬件基礎(

    2024年02月15日
    瀏覽(19)
  • Python基礎(適合初學-完整教程-學習時間一周左右-節(jié)約您的時間)

    Python基礎(適合初學-完整教程-學習時間一周左右-節(jié)約您的時間)

    Python基礎——核心文章 ? ? ? ?本系列博客所有內(nèi)容都是【 實際操作 】為主,部分內(nèi)容一定要解釋說明的會伴隨少量的理論說明,在【 最短時間內(nèi) 】讓大家【 掌握 】真正的【 實操技能 】才是實打實的【 為您創(chuàng)造價值 】。 系統(tǒng)版本:win10、win11 開發(fā)工具:PyCharm Community社

    2024年02月19日
    瀏覽(27)
  • 如何學習python自動化測試,這是我見過最完整的教程了

    如何學習python自動化測試,這是我見過最完整的教程了

    目錄 前言 一、 學習Python基礎知識 二、 學習自動化測試框架 三、 學習Web自動化測試 四、 學習移動端自動化測試 五、 學習版本控制工具 六、 學習測試管理工具 七、 實踐總結 Python自動化測試是目前比較流行的一種自動化測試技術。它具有開發(fā)效率高、可擴展性強、應用廣

    2024年01月19日
    瀏覽(19)
  • 【云計算學習教程】一套完整的云計算產(chǎn)品需要解決哪些問題?_云計算教學問題(1)

    【云計算學習教程】一套完整的云計算產(chǎn)品需要解決哪些問題?_云計算教學問題(1)

    先自我介紹一下,小編浙江大學畢業(yè),去過華為、字節(jié)跳動等大廠,目前阿里P7 深知大多數(shù)程序員,想要提升技能,往往是自己摸索成長,但自己不成體系的自學效果低效又漫長,而且極易碰到天花板技術停滯不前! 因此收集整理了一份《2024年最新大數(shù)據(jù)全套學習資料》,

    2024年04月17日
    瀏覽(22)
  • Yalmip入門教程(1)-入門學習

    Yalmip入門教程(1)-入門學習

    ? ? ? ? 博客中所有內(nèi)容均來源于自己學習過程中積累的經(jīng)驗以及對yalmip官方文檔的翻譯:YALMIP ????????Yalmip的作者是Johan L?fberg,是由Matlab平臺編程實現(xiàn)的一個免費開源數(shù)學優(yōu)化工具箱,在官網(wǎng)上就可以下載。官方下載鏈接如下: Download - YALMIP ????????下載時可以選

    2024年02月15日
    瀏覽(52)
  • Django實戰(zhàn):部署項目 【資產(chǎn)管理系統(tǒng)】,Django完整項目學習研究(項目全解析,部署教程,非常詳細)

    Django實戰(zhàn):部署項目 【資產(chǎn)管理系統(tǒng)】,Django完整項目學習研究(項目全解析,部署教程,非常詳細)

    關于Django,我已經(jīng)和大家分享了一些知識,考慮到一些伙伴需要在實際的項目中去理解。所以我上傳了一套Django的項目學習源碼,已經(jīng)和本文章進行了綁定。大家可以自行下載學習,考慮到一些伙伴是初學者,幾年前,編者也是從初學者一路學習到現(xiàn)在。當時,很希望有一套

    2024年02月20日
    瀏覽(22)
  • 0基礎學習VR全景平臺篇第38章:場景功能-AI虛擬人實操完整教程

    0基礎學習VR全景平臺篇第38章:場景功能-AI虛擬人實操完整教程

    AI虛擬人功能正式上線! ? 依托“虛擬數(shù)字人引擎”結合VR全景,為各行各業(yè)提供虛擬形象生成、驅動、交互服務,幫助海量用戶的VR全景作品,打造成為更具沉浸感的VR交互項目,提升作品變現(xiàn)能力。 功能位置示意 一、什么是AI虛擬人? ? AI虛擬人是指,通過蛙色VR系統(tǒng)生成

    2024年02月09日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包