在Spring Boot 2中有什么新內(nèi)容?

A look at new features in Spring Framework 5 & Spring Boot 2

Spring Boot 2剛剛發(fā)布,在最近的幾個(gè)月里,我很興奮地看到它不停的在更新。這個(gè)版本是17個(gè)月的工作的最高點(diǎn)的見(jiàn)證,由215個(gè)不同的人提交超過(guò)了6800次。有一些很棒的功能可以討論,讓我們來(lái)討論一下Spring Boot 2中的新特性。

在這篇文章中我們將會(huì)看到:

  • Spring Boot的歷史
  • Spring Boot中的新東西
  • Spring Boot 2 遷移指南
  • 其他的資源

Spring Boot的歷史

在我們深入看新的變化之前我們先借這個(gè)機(jī)會(huì)來(lái)了解一下Spring Boot的歷史。這篇博客在2013年8月發(fā)布,Phil Webb宣布了一個(gè)名為Spring Boot的新項(xiàng)目的第一個(gè)里程碑版本。

Spring Boot的目標(biāo)是使創(chuàng)建Spring驅(qū)動(dòng)的、生產(chǎn)級(jí)的應(yīng)用程序和服務(wù)更加容易。它采用了Spring平臺(tái)的有主見(jiàn)的觀點(diǎn),以便新的和現(xiàn)有的用戶(hù)能夠快速地獲得他們需要的東西。您可以使用它來(lái)創(chuàng)建獨(dú)立的Java應(yīng)用程序,可以使用“Java -jar”或更傳統(tǒng)的WAR部署開(kāi)始。

大約9個(gè)月后,2014年4月,Spring Boot 1.0發(fā)布了。從那以后,已經(jīng)有無(wú)數(shù)次的小發(fā)行,給我們帶來(lái)了一些真正偉大的特性。

  • Spring Boot 1.1 (June 2014)

    • spring-boot-starter-test
    • Metrics & Health Endpoints
    • Elastic Search, Apache Solr, Spring
    • Social & Spring Integration Auto-configuration
    • Additional Templating support (Adding Freemaker, Groov, and Velocity)
  • Spring Boot 1.2 (March 2015)

    • Servlet 3.1, Tomcat 8 & Jetty 9
    • Spring 4.1
    • @SpringBootApplication Annotation
      Email Support

Spring 有什么新內(nèi)容

Spring Boot 2的新產(chǎn)品是什么?如果我們要討論最大的特性,我們需要從升級(jí)到Spring Framework 5開(kāi)始。雖然Spring Framework 5自2017年9月就已經(jīng)發(fā)布了,但大多數(shù)開(kāi)發(fā)人員(像我一樣)一直在等待Spring Boot 2的發(fā)布。Spring Framework 5引入了一長(zhǎng)串的新特性,但我只是想介紹一下這里的幾個(gè)主要功能。

在Spring Framework 5中有什么新內(nèi)容!

Java 8+ 最低要求

如果您希望構(gòu)建Spring框架應(yīng)用程序,那么您必須至少使用Java 8。你的第一個(gè)想法可能是,這對(duì)我們所有人來(lái)說(shuō)都是一個(gè)巨大的改變,但實(shí)際上它對(duì)Spring團(tuán)隊(duì)來(lái)說(shuō)是一個(gè)更大的變化。這給了他們一個(gè)機(jī)會(huì)來(lái)進(jìn)行一些重大的更改,以更新代碼庫(kù),以更新Java 8中的所有新特性,如Lambdas和streams。這不僅在整個(gè)代碼中具有可讀性,而且還對(duì)框架的核心提供了一些性能改進(jìn)。

支持 Java9

如果您想使用Java 9,您需要更新Spring Framework 5,因此需要更新Spring Boot 2。我知道我們很多人可能不會(huì)在生產(chǎn)中使用最新的和最偉大的Java版本,但是這是一個(gè)很好的機(jī)會(huì),讓你可以玩所有的酷新玩具。使用標(biāo)準(zhǔn)的類(lèi)路徑可以很好地完成這個(gè)工作,但是我已經(jīng)讀過(guò)一些人在遷移到Java 9模塊時(shí)遇到的問(wèn)題。

Spring MVC

雖然Spring MVC并不是這個(gè)故事的主要角色,但是有一些很好的升級(jí)。我不會(huì)在這里一一講解這些內(nèi)容,因此,我將介紹 Spring Framework 5的文檔.

Spring WebFlux

在Spring Framework 5的故事中,反應(yīng)堆棧(reactive stack)是我們的主要角色。這是一種不同的思考方式,但對(duì)我們來(lái)說(shuō)幸運(yùn)的是,我們不需要學(xué)習(xí)一種全新的編程方式。Spring WebFlux是一種完全異步和非阻塞的web框架,它可以讓我們處理大量并發(fā)連接。這是一個(gè)完全的新的范例轉(zhuǎn)換,并且我們可以很容易的開(kāi)始。


reactive_stack.png

支持Kotlin

Kotlin支持被添加到http://start.spring.io但是在Spring Framework 5中有專(zhuān)門(mén)的語(yǔ)言支持。有了專(zhuān)門(mén)的支持,您可以在這里看到一些不錯(cuò)的特性。 read about here.

測(cè)試改進(jìn)

測(cè)試環(huán)境的最大變化是對(duì)JUnit 5JUnit 5的Jupiter編程和擴(kuò)展模型的完全支持。稍后我將再次提到這一點(diǎn),但是當(dāng)您啟動(dòng)一個(gè)新的Spring Boot 2應(yīng)用程序時(shí),您仍然使用JUnit 4,但是如果您想開(kāi)始使用JUnit 5,那么它是一個(gè)簡(jiǎn)單的更改。

在Spring Boot 2中有什么新東西!

第三方庫(kù)的升級(jí)

隨著Spring Boot的任何新版本的發(fā)布,Spring團(tuán)隊(duì)有機(jī)會(huì)更新各種依賴(lài)關(guān)系。

  • Thymeleaf 3 *
  • Jetty 9.4
  • Tomcat 8.5
  • Hibernate 5.2
  • Flyway 5
  • Gradle 4
  • Thymeleaf啟動(dòng)器現(xiàn)在包括了Thymeleaf -extras-java8time out of The box。

Reactive Spring Data & Spring Security

隨著Spring WebFlux的發(fā)展,Spring數(shù)據(jù)也為反應(yīng)性應(yīng)用提供了支持。目前,Cassandra、MongoDB、Couchbase和Redis都有活性API支持。Spring Boot包含了所有這些應(yīng)該讓開(kāi)始變得非常簡(jiǎn)單的starter- pom。

我們還獲得了在反應(yīng)性應(yīng)用程序中使用Spring Security 5.0的能力。當(dāng)Spring Security在類(lèi)路徑上時(shí),自動(dòng)配置為WebFlux應(yīng)用程序提供。

Actuator

Spring引導(dǎo)驅(qū)動(dòng)器并不是什么新東西,但是它已經(jīng)從頭開(kāi)始重寫(xiě)了。如果您不熟悉執(zhí)行器項(xiàng)目,它會(huì)自動(dòng)公開(kāi)端點(diǎn),以獲取關(guān)于應(yīng)用程序狀態(tài)的信息。在Spring Boot 1.x中的執(zhí)行器是針對(duì)servlet API編寫(xiě)的,并且伴隨著新的反應(yīng)式堆棧,Spring團(tuán)隊(duì)需要一個(gè)能夠同時(shí)處理這兩個(gè)問(wèn)題的解決方案。與此同時(shí),執(zhí)行器有許多變化:

  • Redesign for both servlet & reactive
  • Status & health (all the details) were separated out
  • Simplified Security model
  • Move to micrometer (think SLF4J but for metrics)
  • Improved JSON Structures
  • Simplified process for creating User-Defined Endpoints.
    • @Endpoint
    • @WebEndpoint
    • @JmxEndpoint

有一個(gè)專(zhuān)門(mén)的關(guān)于Spring Boot Actuator Web API端點(diǎn)的詳細(xì)文檔,這是一個(gè)很好的起點(diǎn)。Spring Boot Actuator Web API端點(diǎn)的詳細(xì)文檔 and this is a great place to start.

Gradle Plugin

我一直都是Gradle的忠實(shí)粉絲,我很高興看到團(tuán)隊(duì)利用這個(gè)機(jī)會(huì)重寫(xiě)了Gradle插件。

Spring Boot Gradle插件在Gradle中提供了Spring引導(dǎo)支持,允許您打包可執(zhí)行jar或war歸檔,運(yùn)行Spring引導(dǎo)應(yīng)用程序,并使用Spring - Boot依賴(lài)項(xiàng)提供的依賴(lài)項(xiàng)管理。Spring Boot的Gradle插件需要Gradle 4.0或更高版本。

Getting Started

要開(kāi)始使用插件,它需要應(yīng)用到您的項(xiàng)目中。


buildscript {
    repositories {
        maven { url 'https://repo.spring.io/libs-milestone' }
    }

    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RC1'
    }
}

apply plugin: 'org.springframework.boot'


構(gòu)建可執(zhí)行的jars和wars

bootRepackage任務(wù)已經(jīng)替換為bootJar和bootWar任務(wù),分別用于構(gòu)建可執(zhí)行的jar和war。這兩項(xiàng)任務(wù)都擴(kuò)展了它們的等效標(biāo)準(zhǔn)Gradle jar或war任務(wù),使您能夠訪(fǎng)問(wèn)所有通常的配置選項(xiàng)和行為。

依賴(lài)管理

Spring Boot的Gradle插件不再自動(dòng)應(yīng)用依賴(lài)管理插件。相反,Spring Boot的插件現(xiàn)在會(huì)對(duì)依賴(lài)管理插件進(jìn)行響應(yīng),導(dǎo)入正確版本的Spring - Boot依賴(lài)BOM。這使您能夠更好地控制如何以及何時(shí)配置依賴(lài)關(guān)系管理。對(duì)于大多數(shù)應(yīng)用程序來(lái)說(shuō),應(yīng)用依賴(lài)管理插件是足夠的:

apply plugin: 'io.spring.dependency-management'

Gradle插件也有自己的文檔,里面有一些非常棒的信息。任何想要開(kāi)始使用Gradle的人都應(yīng)該從下面的鏈接開(kāi)始。Gradle Plugin also has its own documentation

簡(jiǎn)化安全

在Spring Boot 2.x中,主要的目標(biāo)之一是簡(jiǎn)化安全配置,使添加自定義安全性變得容易。默認(rèn)情況下,一切都是安全的,包括靜態(tài)資源和執(zhí)行器端點(diǎn)。如果SSpring Security位于類(lèi)路徑上,Spring Boot將添加@EnableWebSecurity,并依賴(lài)Spring Security的 content-negoation來(lái)決定使用哪種身份驗(yàn)證機(jī)制。

一旦用戶(hù)決定要添加自定義安全性,Spring Boot提供的默認(rèn)安全配置將完全退出。此時(shí),用戶(hù)需要顯式地定義他們想要保護(hù)的所有的東西。這意味著現(xiàn)在安全配置在一個(gè)地方,避免與現(xiàn)有WebSecurityConfigurerAdapters任何類(lèi)型的排序問(wèn)題。

下面是一個(gè)自定義security的例子:

http
    .authorizeRequests()
        // 1
        .requestMatchers(EndpointRequest.to("status", "info"))
            .permitAll()
        // 2
        .requestMatchers(EndpointRequest.toAnyEndpoint())
            .hasRole("ACTUATOR")
        // 3 
        .requestMatchers(StaticResourceRequest.toCommonLocations())
            .permitAll()
        // 4
        .antMatchers("/**")
            .hasRole("USER")
    .and()
  ... // additional configuration
  1. /status and /info 斷點(diǎn)不需要認(rèn)證.
  2. 所有其他應(yīng)用程序端點(diǎn)都受ACTUATOR角色的保護(hù)。
  3. 公共靜態(tài)資源位置對(duì)所有人開(kāi)放.
  4. 所有其他應(yīng)用程序端點(diǎn)都受用戶(hù)USER的保護(hù)。

Actuator Security

隨著執(zhí)行器端點(diǎn)被鎖定,您將需要包含或排除您希望看到的端點(diǎn)。這些是現(xiàn)在控制的屬性,從1.x開(kāi)始變化。

端點(diǎn)WEB配置(WebEndpointProperties)

management.endpoints.web.exposure.include=info,health # Endpoint IDs that should be included or '*' for all.
management.endpoints.web.exposure.exclude= # Endpoint IDs that should be excluded.
management.endpoints.web.base-path=/actuator # Base path for Web endpoints. Relative to server.servlet.context-path or management.server.servlet.context-path if management.server.port is configured.
management.endpoints.web.path-mapping= # Mapping between endpoint IDs and the path that should expose them.

如果您不確定使用什么屬性,多看看常用的應(yīng)用程序?qū)傩晕臋n。common application properties documentation.

支持 HTTP/2

很難相信,但是HTTP 1.1規(guī)范是在1996年發(fā)布的。我認(rèn)為這是毋庸置疑的,但是今天的網(wǎng)絡(luò)是非常不同的。如果您希望在Spring MVC或WebFlux應(yīng)用程序中啟用HTTP/2,可以使用以下屬性。

server.http2.enabled=true
這種支持取決于所選的web服務(wù)器和應(yīng)用程序環(huán)境,因?yàn)樵搮f(xié)議不受JDK8的支持。請(qǐng)查看文檔以了解更多細(xì)節(jié) for more details.

Configuration Properties

在Spring Boot 1.x中。這種輕松綁定的概念得到了支持,這意味著有多種方法可以創(chuàng)建屬性名稱(chēng)(駝峰、下劃線(xiàn)、連字符),并且該屬性將綁定到相同的屬性。

這仍然是一樣的,但是他們獲取的方式是在你自己的代碼中讀取變量的方式。@Value注釋是一個(gè)核心容器特性,它不提供與類(lèi)型安全配置屬性相同的特性。

https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/boot-features-external-config.html#boot-features-external-config-relaxed-binding

Metrics

Spring Boot自己的指標(biāo)已被Micrometer
取代。 Pivotal正在開(kāi)發(fā)這項(xiàng)服務(wù),并迅速在Pivotal內(nèi)部的項(xiàng)目中被采用。

Spring Boot Actuator為Micrometer提供依賴(lài)管理和自動(dòng)配置,Micrometer是一個(gè)支持眾多監(jiān)控系統(tǒng)的應(yīng)用指標(biāo)外觀,其中包括:

想要學(xué)習(xí)更多關(guān)于Micrometer 瀏覽 https://micrometer.io/

這可能會(huì)給那些大量記錄自定義度量的人帶來(lái)一點(diǎn)升級(jí)的痛苦。

Quartz Scheduler

Spring Boot 2提供了對(duì)Quartz Scheduler的支持,它可以通過(guò)Spring - Boot -starter- Quartz專(zhuān)用啟動(dòng)器使用。內(nèi)存和JDBC存儲(chǔ)都可以配置。


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

HikariCP Connection Pool

默認(rèn)連接池已從Tomcat切換到HikariCP。 如果您使用spring.datasource.type強(qiáng)制在基于Tomcat的應(yīng)用程序中使用Hikari,則現(xiàn)在可以刪除該重寫(xiě)。 同樣,如果您想要保留Tomcat連接池,只需將以下內(nèi)容添加到您的配置中即可:

spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource

Developer Tools

默認(rèn)情況下,每次應(yīng)用程序重新啟動(dòng)時(shí),都會(huì)記錄顯示狀態(tài)評(píng)估增量的報(bào)告。報(bào)告顯示了在進(jìn)行更改(如添加或刪除bean和設(shè)置配置屬性)時(shí)對(duì)應(yīng)用程序的自動(dòng)配置的更改。

若要禁用報(bào)告的日志記錄,請(qǐng)?jiān)O(shè)置以下屬性:

spring.devtools.restart.log-condition-evaluation-delta=false

Kotlin Support

我們?cè)谥坝懻撨^(guò)Kotlin 這里是相關(guān)的文檔 documentation to Kotlin.

JUnit 5

正如我前面所說(shuō)的,Spring引導(dǎo)應(yīng)用程序的默認(rèn)值仍然是使用JUnit 4\。如果您想切換到JUnit 5,您將需要從spring引導(dǎo)啟動(dòng)器測(cè)試中排除JUnit 4,并添加所需的依賴(lài)項(xiàng)。您還需要添加下面列出的插件。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-api</artifactId>
    <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
<groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>${junit-platform.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

Spring Boot 2 Migration Guide

這可能是不言而喻的,但是像這樣的任何主要版本,僅僅是在生產(chǎn)中翻轉(zhuǎn)版本號(hào)并不是最好的升級(jí)路徑。我要做的第一件事是閱讀Spring Boot 2.0 Migration Guide。對(duì)我來(lái)說(shuō),我發(fā)現(xiàn)我的大部分問(wèn)題都圍繞著簡(jiǎn)化的安全模型變更和屬性變更。遷移指南包含了遷移您的屬性文件的一個(gè)很棒的技巧。

使用Spring Boot 2.0,許多配置屬性被重命名/刪除,開(kāi)發(fā)人員需要相應(yīng)地更新其application.properties / application.yml。 為了幫助你,Spring Boot發(fā)布了一個(gè)新的spring-boot-properties-migrator模塊。 一旦作為依賴(lài)添加到項(xiàng)目中,這不僅將分析應(yīng)用程序的環(huán)境并在啟動(dòng)時(shí)打印診斷信息,而且還會(huì)在運(yùn)行時(shí)為您暫時(shí)遷移屬性。 這是您的應(yīng)用程序遷移期間必須具備的條件:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-properties-migrator</artifactId>
</dependency>

我不確定你的想法是什么,但是我肯定會(huì)開(kāi)始使用Spring Boot 2并開(kāi)始將代碼遷移到它,但是對(duì)于任何主要版本,我通常都會(huì)等到下一個(gè)版本發(fā)布。 這不僅僅是為了Spring,我從蘋(píng)果,Pivotal到憤怒的小鳥(niǎo),都能做到這一點(diǎn)!

Resources

Documentation

這里有大量的資源,但我想從文檔開(kāi)始。Spring框架和Spring Boot的文檔多年來(lái)確實(shí)得到了改進(jìn)。我喜歡一些專(zhuān)門(mén)的指南,我們這一次用Actuator和Gradle插件。

Conclusion

我期待這個(gè)版本已經(jīng)很長(zhǎng)時(shí)間了,很興奮他的正式發(fā)布。

原文鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評(píng)論 6 535
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,744評(píng)論 3 421
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,879評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,181評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,935評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,325評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,534評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,084評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,892評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,067評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,322評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,735評(píng)論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,990評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,800評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,084評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容