SpringBootDocumentation-Using Spring Boot

1. Build Systems

1.1. Dependency Management

??SpringBoot每個版本都會提供一個它所支持的依賴項列表。你在使用的時候不需要給這些依賴項配置版本,SpringBoot會管理他們。當你升級SpringBoot的時候,這些依賴項也會以一致的方式升級。
??你也可以指定明確的版本,覆蓋SpringBoot推薦的依賴項版本。
??這個依賴項列表包含所有spring啟動時可以使用的spring模塊,以及第三方庫的細化列表。該列表作為標準清單,可以和maven和gradle一起使用。
??每個SpringBoot版本都會和Spring框架的基礎版本相關聯。我們強烈建議,你不要明確指定依賴的版本,使用SpringBoot推薦的版本。

1.2. Maven

Maven使用者可以在spring-boot-starter-parent項目中去獲得一些比較合理的默認配置。這個父依賴提供了以下特性:

  • java1.8作為默認的編譯器級別
  • UTF-8編碼格式
  • 一個版本依賴管理節點,從POM文件中繼承,管理所有公共依賴的版本號,它可以讓我們省略依賴的版本號。
  • 使用重新打包id執行重新打包目標
  • 合理的資源過濾
  • 合理的插件配置

注意:application.properties和application.yml文件接受Spring風格的占位符(${...}),Maven的占位符被改成了使用@....@(你可以使用maven屬性resource.delimiter覆蓋它)

1.2.1. Inheriting the Starter Parent

配置你的工程繼承自spring-boot-starter-parent像下面這樣設置parent屬性:

<!-- Inherit defaults from Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
</parent>

??你只需要在你的依賴中指定SpringBoot的版本號就ok,如果你引入額外的Starters,你可以放心的省略他們的版本號。
??你可以使用properties屬性重寫依賴版本。例如:你想升級SpringData的發布版本,你可以這樣:

<properties>
    <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>

檢查SpringBoot依賴列表(POM)所有支持的屬性:
https://github.com/spring-projects/spring-boot/tree/v2.2.4.RELEASE/spring-boot-project/spring-boot-dependencies/pom.xml

1.2.2. Using Spring Boot without the Parent POM

??不是所有人喜歡繼承spring-boot-starter-parent,你可以有自己的標準的parent,或者您可能更喜歡顯式地聲明所有Maven配置。
??如果你不想使用spring-boot-starter-parent,你仍然可以通過使用scope=import dependency來保持依賴管理(而不是插件管理)的好處,如下所示:

<dependencyManagement>
    <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.4.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

前面的例子不允許你覆蓋某個依賴的版本,為了達到相同的效果,你需要在dependencyManagement增加一個條目。舉個例子:你如果要覆蓋SpringData的版本:

<dependencyManagement>
    <dependencies>
        <!-- Override Spring Data release train provided by Spring Boot -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>Fowler-SR2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>2.2.4.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在上面的例子中我們指定一個BOM,但是所有依賴類型都可以通過這樣的方式修改

1.2.3. Using the Spring Boot Maven Plugin

SpringBoot提供了一個Maven插件來打包項目生成一個可執行的JAR,在<plugins>添加Maven插件如果你想使用它的話:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
1.5. Starters

啟動器是一組非常非常方便的依賴描述符,你可以獲得一站式的Spring服務,比如你想用JPA,你可以使用spring-boot-starter-data-jpa依賴在你的項目當中。

\color{black}{\Large\mathbf{名字是什么意義}}

??所有官方的啟動器使用一個命名格式:spring-boot-starter-*
??第三方的啟動器不要以spring-boot開頭命名,第三方的啟動器可以這樣命名:thirdpartyproject-spring-boot-starter.

2.1. Using the “default” Package

??當一個類不被包含在包里面時,它會被認為當前在默認包下(default package)。使用默認包是不推薦的,應該避免這種使用方法他可能會在使用@ComponentScan、
@ConfigurationPropertiesScan、@EntityScan、@SpringBootApplication注解的時候引起一些問題,因為每個jar包里面的每個類都是可以被訪問的。
??我們推薦使用Java傳統的命名方式,將域名倒寫:com.yu.test

2.2. Locating the Main Application Class

我們推薦把SpringBoot的MainApplication放到一個根目錄下,@SpringBootApplication注釋通常放在主類上,它隱式地為某些項定義了一個基本的“搜索包”。例如,如果您正在編寫一個JPA應用程序,那么@SpringBootApplication注釋類的包將用于搜索@Entity項。

如果你不想使用@SpringBootApplication,你可以使用@EnableAutoConfiguration 和@ComponentScan去代替它

3. Configuration Classes

雖然SpringBootApplication可以和XML文件配合使用,但是我們推薦你把配置源寫成一個單獨的類,使用@Configuration注解

3.1. Importing Additional Configuration Classes

您不需要將所有@Configuration放到單個類中。@Import注釋可用于導入其他配置類。或者,您可以使用@ComponentScan來自動獲取所有Spring組件,包括@Configuration類。

3.2. Importing XML Configuration

如果您必須使用基于XML的配置,我們建議你仍然從@Configuration類開始。然后可以使用@ImportResource注釋來加載XML配置文件。

4. Auto-configuration

??Spring Boot自動配置嘗試根據添加的jar依賴項自動配置Spring應用程序。例如,如果HSQLDB在您的類路徑中,并且您沒有手動配置任何數據庫連接bean,那么Spring Boot將自動配置內存中的數據庫。
??您需要通過將@EnableAutoConfiguration或@SpringBootApplication注釋添加到您的@Configuration類之一來選擇自動配置。
??你應該只添加一個@SpringBootApplication或@EnableAutoConfiguration注釋。我們通常建議只向主@Configuration類添加一個或另一個。

4.1. Gradually Replacing Auto-configuration

??你可以定義自己的Configuration去代替自動配置的某個部分。比如,如果你添加了你自己的DataSource對象,則默認嵌入的數據庫支持將后退。
??如果你想知道自動配置都配置了些什么,或者為什么這樣,你可以用--debug模式啟動程序
??這樣做可以為選擇的核心日志記錄器啟用調試日志,并將條件報告記錄到控制臺。

4.2. Disabling Specific Auto-configuration Classes

如果你不想讓某個自動配置類被應用,那么你可以在@SpringBootApplication中使用“exclude”屬性,去禁用他們:

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class MyApplication {
}

??如果配置類不在類路徑上,你可以使用excludeName屬性去指定它的全限定類路徑。如果你使用@EnableAutoConfiguration,exclude和excludeName也是可以使用的。最后,你也可以使用這個spring.autoconfigure.exclude去排除

5. Spring Beans and Dependency Injection

??如果按照上面的建議構造代碼(將應用程序類定位在根包中),則可以添加@ComponentScan而不需要任何參數。所有應用程序組件(@Component、@Service、@Repository、@Controller等)都自動注冊為Spring bean。

6. Using the @SpringBootApplication Annotation

??一個單獨的@SpringBootApplication 注解可以包含:

  • @EnableAutoConfiguration
  • @ComponentScan
  • @Configuration

7.Hot Swapping

熱部署可以使用JRebel,spring-boot-devtools也支持熱部署

8. Developer Tools

spring-boot-devtools模塊可以被包含在任意的項目以提供一些額外的開發時特性。如果要使用它,在Maven中添加如下依賴:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

在運行完全打包的程序時,將自動禁用開發人員工具。如果你的應用是從"java -jar"或者是從一個特殊的類加載器啟動的時候,它會被認為是一個"production application"。如果你想禁用開發人員工具,那么請排除devtools或者設置-Dspring.devtools.restart.enabled=false系統屬性。

默認情況下,重新打包的歸檔文件不包含devtools。如果你想使用某個遠程devtools特性,您需要禁用excludeDevtools構建屬性來包含它:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>
8.1. Property Defaults

??SpringBoot支持的一些庫使用緩存來提高性能。例如:模板引擎緩存已經編譯的模板,以避免重復解析模板文件。此外,在提供靜態資源時,SpringMVC可以向響應添加HTTP緩存頭。
??當緩存在一個項目中起作用的時候,有時候他會阻止你看到你對項目的更改。所以,spring-boot-devtools默認禁用緩存選項。
??緩存選項通常通過application.properties配置文件配置。例如:
Thymeleaf提供了spring.thymeleaf.cache屬性。
??spring-boot-devtools模塊不需要手動設置這些屬性,而是自動應用合理的開發時配置。
??因為你在開發SpringMVC應用或者Spring WebFlux應用的時候,需要一些關于web請求的信息。所以開發者工具將為web日志組啟用調試日志。它將為您提供有關傳入請求、正在處理它的處理程序、響應結果等信息。如果希望記錄所有請求細節(包括潛在的敏感信息),請打開spring.http.log-request-details配置屬性。

??如果不希望應用屬性默認值,可以將application.properties中的spring.devtools.add-properties設置為false。
??有關devtools應用的屬性的完整列表,請參見DevToolsPropertyDefaultsPostProcessor.

8.2. Automatic Restart

??可以使用spring-boot-devtools當類路徑有文件改動的時候會自動重啟。默認情況下,類路徑中指向文件夾的任何條目都將被監視,以查看是否有更改。請注意,某些資源(如靜態資源和視圖模板)不需要重新啟動應用程序。
\color{black}{\Large\mathbf{觸發一次重啟}}

??由于DevTools監視類路徑資源,觸發重新啟動的唯一方法是更新類路徑。更新類路徑的方式取決于所使用的IDE。在Eclipse中,保存修改后的文件將導致更新類路徑并觸發重啟。在IntelliJ IDEA中,構建項目(Build +→+ Build項目)具有相同的效果。

??當與LiveReload一起使用時,自動重啟效果非常好。有關詳細信息,請參閱LiveReload部分。See the LiveReload section
如果使用JRebel,則禁用自動重新啟動,以便動態類重新加載。其他devtools特性(如LiveReload和屬性覆蓋)仍然可以使用。

??DevTools依賴于應用程序上下文的shutdown hook在重啟時關閉它。如果您禁用了它(SpringApplication.setRegisterShutdownHook(false)),它就不能正常工作。

??當決定類路徑上的一個條目更改時是否應該觸發重啟時,DevTools會自動忽略名為springboot,springboot-devtools,springboot-autoconfigure,springboot-actuator和springboot-starter

??DevTools需要自定義ApplicationContext使用的ResourceLoader。如果您的應用程序已經提供了一個,那么它將被包裝。不支持直接覆蓋ApplicationContext上的getResource方法。

\color{black}{\Large\mathbf{Restart vs Reload}}

??SpringBoot提供的重啟技術工作在兩個類加載器上面。不更改的類(例如,來自第三方jar的類)被加載到基類加載器中。您正在積極開發的類被加載到一個restart類加載器中。當應用程序重新啟動時,將丟棄restart類加載器并創建一個新類加載器。這種方法意味著應用程序重新啟動通常比“冷啟動”快得多,因為基類加載器已經可用并被填充了。

??如果您發現重新啟動對于您的應用程序來說不夠快,或者您遇到了類加載問題,那么您可以考慮重新加載技術,例如來自ZeroTurnaround的JRebel。這些工作是通過在裝入類時重寫它們,使它們更易于重新裝入。

8.2.1. Logging changes in condition evaluation

??默認情況下,每次應用程序重新啟動時,都會記錄一個顯示條件評估增量的報告。當您進行更改(如添加或刪除bean和設置配置屬性)時,該報告將顯示對應用程序的自動配置的更改。
??如果你想禁用他,設置這個屬性:

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

8.2.2. Excluding Resource

??某些資源在更改時不一定需要重新啟動。例如,Thymeleaf模板可以就地編輯。默認情況下,更改/META-INF/maven、/META-INF/resources、/resources、/static、/public或/templates中的資源不會觸發重啟,但會觸發動態重新加載。如果您想要自定義這些排除,您可以使用spring.devtools.restart.exclude屬性。例如,要僅排除/static和/public,您需要設置以下屬性:

spring.devtools.restart.exclude=static/**,public/**

8.2.3. Excluding Resource

??當你更改不在類路徑上的文件時,您可能希望重新啟動或重新加載應用程序。為此,請使用spring.devtools.restart.additional-paths屬性配置其他路徑以監視更改。你可以使用前面描述的spring.devtools.restart.exclude屬性來控制附加路徑下的更改是觸發完全重新啟動還是部分重新加載。

8.2.4. Disabling Restart

??如果你不希望使用熱部署,你可以使用spring.devtools.restart.enabled屬性禁用他。在大多數情況下,可以在應用程序中設置此屬性(這樣做仍然會初始化restart classloader,但它不會監視文件更改)。
??如果你想完全禁用它,你可以在調用SpringApplication.run之前將spring.devtools.restart.enabled系統屬性設置為false。像下面這樣:

public static void main(String[] args) {
    System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(MyApp.class, args);
}

8.2.5. Using a Trigger File

??如果您使用的IDE不斷地編譯更改后的文件,那么您可能更希望只在特定的時間觸發重新啟動。為此,您可以使用一個“觸發器文件”,它是一個特殊的文件,當您想要實際觸發重啟檢查時,必須對其進行修改。
??對文件的任何更新都將觸發一次檢查,但是只有在Devtools檢測到需要執行某些操作時,才會實際重新啟動。
??設置spring.devtools.restart.trigger-file屬性指定你的觸發器文件的位置,觸發器文件必須出現在類路徑中的某個位置。
例如:使用下面的目錄結構:

src
+- main
  +- resources
     +- .reloadtrigger

??然后你的applictaion.properties文件的屬性設置為:spring.devtools.restart.trigger-file=.reloadtrigger
??現在只有在triggerFile發生更新的時候才會重新啟動

8.2.6. Customizing the Restart Classloader

??在前面的Restart vs Reload一節中所描述過,重新啟動功能是通過使用兩個類加載器實現的。對于大多數應用程序,這種方法工作得很好。然而,它有時會導致類加載問題。
??默認情況下,IDE中任何打開的項目都是用“restart”類加載器加載的,而任何常規的.jar文件都是用“base”類加載器加載的。如果你處理的是一個多模塊項目,而不是每個模塊都導入到IDE中,那么您可能需要自定義一些東西。為此,您可以創建一個META-INF/spring-devtools屬性文件。
??spring-devtools.properties文件可以包含restart.exclude和restart.include的前綴。include屬性包含的元素是應該被拉入“restart”類加載器的屬性,exclude包含的屬性是應該被拉入“base”類加載器的屬性。
屬性的值是一個正則表達式,如下面:

restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\.]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\.]+\.jar

8.2.7. Known Limitations

??對于使用標準的ObjectInputStream反序列化的對象,重新啟動不能很好的工作。如果你需要反序列化數據,你需要使用Spring的ConfigurableObjectInputStream和Thread.currentThread().getContextClassLoader()相結合。

8.3. LiveReload

??spring-boot-devtools模塊包含一個內嵌的LiveReload服務器,可以用來在資源更改時觸發瀏覽器刷新。LiveReload瀏覽器擴展可免費用于Chrome、Firefox和Safari livereload.com.
如果你不想讓LiveReload服務運行,那么你可以設置spring.devtools.livereload.enabled屬性為false
??一次只能運行一個LiveReload服務器。在啟動應用程序之前,請確保沒有其他的LiveReload服務器在運行。如果您從IDE啟動多個應用程序,那么只有第一個具有LiveReload支持。

8.4. Global Settings

??你可以向$HOME/.config/spring-boot目錄添加以下文件來配置全局devtools設置:

spring-boot-devtools.properties
spring-boot-devtools.yaml
spring-boot-devtools.yml

??添加到這些文件中的任何屬性都適用于您機器上使用devtools的所有的Spring啟動應用程序。例如,要將restart配置為始終使用觸發器文件,您需要添加以下屬性:

// 文件路徑
~/.config/spring-boot/spring-boot-devtools.properties
// 添加的屬性
spring.devtools.restart.trigger-file=.reloadtrigger

??如果在$HOME/.config/spring-boot中沒有找到devtools配置文件。將會在根目錄($HOME)下搜索是否存在spring-boot-devtools.properties文件。這允許您與不支持$HOME/.config/spring-boot/的舊版Spring Boot的應用程序共享devtools全局配置.

8.5. Remote Applications

??開發人員工具并不局限于本地開發使用,在遠程運行應用程序時,也可以使用。但是它存在一定的安全風險, 只有在受信任的網絡上運行或者使用SSL進行保護時,才應該啟用它。如果這兩個選項都不可用,就不應該使用DevTools的遠程支持。永遠不要在生產部署上啟用支持。
??要啟用它,您需要確保重新打包的歸檔文件中包含devtools,如下面的清單所示:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

??然后需要設置spring.devtools.remote.secret屬性。與任何重要的密碼或秘密一樣,該值應該是唯一的、強的,這樣就不會被猜測或強行使用。
??遠程devtools支持由兩部分提供:接受連接的服務器端端點和在IDE中運行的客戶機應用程序。當設置spring.devtools.remote.secret屬性時,服務器組件將自動啟用。客戶端組件必須手動啟動。

8.5.1. Running the Remote Client Application

??遠程客戶端應用程序被設計在IDE中運行。您需要使用與您連接的遠程項目相同的類路徑來運行org.springframework.boot.devtools.RemoteSpringApplication。應用程序唯一需要的參數是它所連接的遠程URL。
??例如,如果你正在使用IDEA,并且你有一個名為my-app的項目,你已經部署到云服務器,你會做以下事情:

1.在Run菜單中選擇"Edit Configurations"


image.png

2.創建一個新的啟動配置,選擇SpringBoot,并且選擇你的Remote主程序,你如你的Remote主程序的名字是”org.springframework.boot.devtools.RemoteSpringApplication“


image.png
  1. 把你的遠程URL填到 "program arguments"屬性列里面

??注意:通常建議使用https://作為連接協議,這樣就可以對流量進行加密,并且不會截獲密碼。
??如果需要使用代理訪問遠程應用程序,請配置spring.devtools.remote.proxy.hostspring.devtools.remote.proxy.port屬性。

8.5.3. Configuring File System Watcher

??FileSystemWatcher的工作方式是,在一定的時間間隔內輪詢類更改,然后等待預定義的靜默期,以確保不再發生更改。然后將更改上傳到遠程應用程序。在較慢的開發環境中,可能會發生這樣的情況:安靜期不夠長,類中的更改可能被分割為多個批。上傳第一批類更改后,服務器將重新啟動。下一批數據不能發送到應用程序,因為服務器正在重新啟動。
??可能會發生一些RemoteSpringApplication日志中關于上傳一些類失敗的警告,以及隨后的重試。但是,它也可能導致應用程序代碼不一致,并且在上傳第一批更改后無法重新啟動。

如果你經常觀察到這種現象,請嘗試將spring.devtools.restart.poll-interval和spring.devtools.restart.quiet-period參數增加到適合您的開發環境的值:

spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s

這樣的配置的意識是被監視的classpath文件夾現在每2秒輪詢一次,以查找更改,并保持1秒的靜默期,以確保沒有其他類更改。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容