Spring Boot 2.0.0參考手冊_中英文對照_Part IV_23

文章作者:Tyan
博客:noahsnail.com ?|? CSDN ?|? 簡書

Part IV. Spring Boot features

This section dives into the details of Spring Boot. Here you can learn about the key features that you will want to use and customize. If you haven’t already, you might want to read the Part II, “Getting started” and Part III, “Using Spring Boot” sections so that you have a good grounding of the basics.

這一部分進入Spring Boot細節(jié)部分。在這部分你會了解到你想使用和定制的一些重要特性。如果你還沒準備好杯活,你可以閱讀第二部分“Getting started”和第三部分“Using Spring Boot”御滩,可以對基礎(chǔ)知識有個較好的認識怎茫。

23. SpringApplication

The SpringApplication class provides a convenient way to bootstrap a Spring application that will be started from a main() method. In many situations you can just delegate to the static SpringApplication.run method:

SpringApplication提供了一種很方便的方式來引導Spring應(yīng)用,Spring應(yīng)用可以從main()方法中啟動奴愉。許多情況下你可以委托給靜態(tài)方法SpringApplication.run

public static void main(String[] args) {
    SpringApplication.run(MySpringConfiguration.class, args);
}

When your application starts you should see something similar to the following:

當你的應(yīng)用啟動時你應(yīng)該看到類似于下面的東西:

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v1.4.2.RELEASE

2013-07-31 00:08:16.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166  INFO 56603 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912  INFO 41370 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501  INFO 41370 --- [           main] o.s.b.s.app.SampleApplication            : Started SampleApplication in 2.992 seconds (JVM running for 3.658)

By default INFO logging messages will be shown, including some relevant startup details such as the user that launched the application.

默認情況下會輸出INFO日志信息蔬螟,包括一些相關(guān)的啟動細節(jié)例如啟動應(yīng)用的用戶此迅。

23.1 Startup failure

If your application fails to start, registered FailureAnalyzers get a chance to provide a dedicated error message and a concrete action to fix the problem. For instance if you start a web application on port 8080 and that port is already in use, you should see something similar to the following:

如果你的應(yīng)用啟動失敗,注冊FailureAnalyzers有可能會提供專門的錯誤信息和解決這個問題的具體行動。例如邮屁,如果你啟動一個8080端口的web應(yīng)用并且這個端口已經(jīng)被占用整袁,你應(yīng)該會看到類似于下面的內(nèi)容:

***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

Spring Boot provides numerous FailureAnalyzer implementations and you can add your own very easily.

?

Spring Boot提供了許多FailureAnalyzer實現(xiàn),你可以很容易添加自己的FailureAnalyzer實現(xiàn)佑吝。

If no failure analyzers are able to handle the exception, you can still display the full auto-configuration report to better understand what went wrong. To do so you need to enable the debug property or enable DEBUG logging for org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer.

如果沒有失敗分析器能處理這個異常坐昙,你仍可以顯示完整的自動配置報告,從而更好的理解什么地方出問題了芋忿。為了實現(xiàn)這個你需要啟用debug屬性或啟用org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializerDEBUG日志炸客。

For instance, if you are running your application using java -jar you can enable the debug property as follows:

例如,如果你使用java -jar運行應(yīng)用戈钢,你可以用下面的形式啟用debug屬性:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2 Customizing the Banner

The banner that is printed on start up can be changed by adding a banner.txt file to your classpath, or by setting banner.location to the location of such a file. If the file has an unusual encoding you can set banner.charset (default is UTF-8). In addition to a text file, you can also add a banner.gif, banner.jpg or banner.png image file to your classpath, or set a banner.image.location property. Images will be converted into an ASCII art representation and printed above any text banner.

啟動時打印的標語可以通過在classpath中添加一個banner.txt文件或者將banner.location設(shè)置為banner.txt文件的位置來修改痹仙。如果文件是一種不常見的編碼方式,你可以設(shè)置banner.charset(默認是UTF-8)殉了。除了文本文件之外开仰,你也添加一個banner.gifbanner.jpgbanner.png圖像文件到classpath中薪铜,或者設(shè)置一個banner.image.location屬性众弓。圖像將被轉(zhuǎn)換成ASCII藝術(shù)表示并打印在文本標語之上。

Inside your banner.txt file you can use any of the following placeholders:

banner.txt內(nèi)部你可以使用下面的任何占位符:

Table 23.1. Banner variables

Variable Description
${application.version} The version number of your application as declared in MANIFEST.MF. For example Implementation-Version: 1.0 is printed as 1.0.
${application.formatted-version} The version number of your application as declared in MANIFEST.MF formatted for display (surrounded with brackets and prefixed with v). For example (v1.0).
${spring-boot.version} The Spring Boot version that you are using. For example 1.4.2.RELEASE.
${spring-boot.formatted-version} The Spring Boot version that you are using formatted for display (surrounded with brackets and prefixed with v). For example (v1.4.2.RELEASE).
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) Where NAME is the name of an ANSI escape code. See AnsiPropertySource for details.
${application.title} The title of your application as declared in MANIFEST.MF. For example Implementation-Title: MyApp is printed as MyApp.

Table 23.1. Banner變量

Variable Description
${application.version} 你的應(yīng)用的版本號在MANIFEST.MF中聲明隔箍。 例如Implementation-Version: 1.0打印成1.0.
${application.formatted-version} MANIFEST.MF中的聲明的應(yīng)用版本號進行格式化顯示(加上前綴v并用括號包裹)谓娃。例如(v1.0)
${spring-boot.version} 你使用的Spring Boot版本蜒滩。例如1.4.2.RELEASE.
${spring-boot.formatted-version} 你使用的Spring Boot版本進行格式化顯示加上前綴v并用括號包裹)滨达。例如(v1.4.2.RELEASE)
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) NAME是ANSI轉(zhuǎn)義碼的名字俯艰。更多細節(jié)請看AnsiPropertySource捡遍。
${application.title} MANIFEST.MF中聲明的應(yīng)用標題。例如Implementation-Title: MyApp打印成MyApp.

The SpringApplication.setBanner(…?) method can be used if you want to generate a banner programmatically. Use the org.springframework.boot.Banner interface and implement your own printBanner() method.

?

如果你想自動生成一個標語你可以使用SpringApplication.setBanner(…?)方法蟆炊。使用org.springframework.boot.Banner接口并實現(xiàn)你自己的printBanner()方法稽莉。

You can also use the spring.main.banner-mode property to determine if the banner has to be printed on (console), using the configured logger (log) or not at all (off).

你也可以使用spring.main.banner-mode屬性來決定標語是否必須在System.out(控制臺)上輸出瀑志,使用配置的日志(log)或一點也不用(off)涩搓。

The printed banner will be registered as a singleton bean under the name pringBootBanner.

輸出的banner會注冊名字為pringBootBanner的單例bean。

YAML maps off to false so make sure to add quotes if you want to disable the banner in your application.

spring:
    main:
        banner-mode: "off"

?

如果你想在你的應(yīng)用中禁用banner劈猪,YAML會將off映射為false昧甘,因此要確保添加引用。

spring:
    main:
        banner-mode: "off"

23.3 Customizing SpringApplication

If the SpringApplication defaults aren’t to your taste you can instead create a local instance and customize it. For example, to turn off the banner you would write:

如果你不喜歡默認的SpringApplication战得,你可以創(chuàng)建一個本地實例并定制它充边。例如,關(guān)閉你寫的banner:

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

The constructor arguments passed to SpringApplication are configuration sources for spring beans. In most cases these will be references to @Configuration classes, but they could also be references to XML configuration or to packages that should be scanned.

?

傳給SpringApplication的構(gòu)造函數(shù)參數(shù)是Spring beans配置源。在大多數(shù)情況下將會引用@Configuration類浇冰,但它們也可以引用XML配置或應(yīng)該掃描的包贬媒。

It is also possible to configure the SpringApplication using an application.properties file. See Chapter 24, Externalized Configuration for details.

也可以使用application.properties文件配置SpringApplication。更多細節(jié)請看24章肘习,『外部配置』际乘。

For a complete list of the configuration options, see the SpringApplication Javadoc.

完整的配置選項列表,請看SpringApplication文檔漂佩。

23.4 Fluent builder API

If you need to build an ApplicationContext hierarchy (multiple contexts with a parent/child relationship), or if you just prefer using a fluent builder API, you can use the SpringApplicationBuilder.

如果你需要構(gòu)建ApplicationContext分層(多個具有父/子關(guān)系的上下文)脖含,或者你更喜歡使用fluent的構(gòu)建器API,你可以使用SpringApplicationBuilder投蝉。

The SpringApplicationBuilder allows you to chain together multiple method calls, and includes parent and child methods that allow you to create a hierarchy.

SpringApplicationBuilder允許你鏈接多個方法調(diào)用养葵,包括允許你創(chuàng)建分層的parentchild方法。

For example:

例如:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);

There are some restrictions when creating an ApplicationContext hierarchy, e.g. Web components must be contained within the child context, and the same Environment will be used for both parent and child contexts. See the SpringApplicationBuilder Javadoc for full details.

?

當創(chuàng)建ApplicationContext分層時有一些限制瘩缆,例如关拒,子上下文必須包含web組件,父子上下文將使用同一個Environment庸娱。更完整的細節(jié)請看SpringApplicationBuilder文檔夏醉。

23.5 Application events and listeners

In addition to the usual Spring Framework events, such as ContextRefreshedEvent, a SpringApplication sends some additional application events.

除了平常的Spring框架事件之外,例如ContextRefreshedEvent涌韩,SpringApplication會發(fā)送一些其它的應(yīng)用事件畔柔。

Some events are actually triggered before the ApplicationContext is created so you cannot register a listener on those as a @Bean. You can register them via the SpringApplication.addListeners(…?) or SpringApplicationBuilder.listeners(…?) methods.

If you want those listeners to be registered automatically regardless of the way the application is created you can add a META-INF/spring.factories file to your project and reference your listener(s) using the org.springframework.context.ApplicationListener key.

org.springframework.context.ApplicationListener=com.example.project.MyListener

?

ApplicationContext創(chuàng)建之前實際上會觸發(fā)一些事件,因此你不能使用@Bean來注冊這些監(jiān)聽器臣樱。你可以通過SpringApplication.addListeners(…?)SpringApplicationBuilder.listeners(…?)方法來注冊這些監(jiān)聽器靶擦。

如果你想自動注冊這些監(jiān)聽器,不管上下文的創(chuàng)建方式雇毫,你可以在你的工程中添加META-INF/spring.factories文件玄捕,并通過org.springframework.context.ApplicationListener作為key來引用你的監(jiān)聽器。

org.springframework.context.ApplicationListener=com.example.project.MyListener

Application events are sent in the following order, as your application runs:

  1. An ApplicationStartedEvent, but before any processing except the registration of listeners and initializers.
  2. An ApplicationEnvironmentPreparedEvent is sent when the Environment to be used in the context is known, but before the context is created.
  3. An ApplicationPreparedEvent is sent just before the refresh is started, but after bean definitions have been loaded.
  4. An ApplicationReadyEvent is sent after the refresh and any related callbacks have been processed to indicate the application is ready to service requests.
  5. An ApplicationFailedEvent is sent if there is an exception on startup.

當你的應(yīng)用運行時棚放,應(yīng)用事件以下面的順序發(fā)送:

  1. 在運行啟動時發(fā)送ApplicationStartedEvent枚粘,除了監(jiān)聽器和初始化器注冊之外,在進行任何處理之前發(fā)送飘蚯。
  2. 當在上下文中使用的Environment已知時馍迄,發(fā)送ApplicationEnvironmentPreparedEvent,但發(fā)送是在上下文創(chuàng)建之前局骤。
  3. 在再刷新啟動之前攀圈,但在bean定義加載之后,發(fā)送ApplicationPreparedEvent峦甩。
  4. 在再刷新之后赘来,發(fā)送ApplicationReadyEvent,任何相關(guān)的回調(diào)函數(shù)都處理完成之后,意味著應(yīng)用已經(jīng)準備處理服務(wù)請求了犬辰。
  5. 如果啟動時出現(xiàn)異常嗦篱,發(fā)送ApplicationFailedEvent.

You often won’t need to use application events, but it can be handy to know that they exist. Internally, Spring Boot uses events to handle a variety of tasks.

?

經(jīng)常你不需要使用應(yīng)用事件,但知道它們的存在是便利的幌缝。Spring Boot內(nèi)部使用事件來處理大量的任務(wù)默色。

23.6 Web environment

A SpringApplication will attempt to create the right type of ApplicationContext on your behalf. By default, an AnnotationConfigApplicationContext or AnnotationConfigEmbeddedWebApplicationContext will be used, depending on whether you are developing a web application or not.

SpringApplication會嘗試創(chuàng)建代表你的合適的ApplicationContext類型。默認情況下狮腿,會使用AnnotationConfigApplicationContextAnnotationConfigEmbeddedWebApplicationContext腿宰,依賴于你是否在開發(fā)一個web應(yīng)用。

The algorithm used to determine a ‘web environment’ is fairly simplistic (based on the presence of a few classes). You can use setWebEnvironment(boolean webEnvironment) if you need to override the default.

使用的決定web environment的算法是相對簡單的(基于現(xiàn)有的一些類)缘厢。如果你需要覆寫默認值你可以使用setWebEnvironment(boolean webEnvironment)吃度。

It is also possible to take complete control of the ApplicationContext type that will be used by calling setApplicationContextClass(…?).

完全控制ApplicationContext類型也是可能的,通過調(diào)用setApplicationContextClass(…?)使用贴硫。

It is often desirable to call setWebEnvironment(false) when using SpringApplication within a JUnit test.

?

當在JUnit測試時使用SpringApplication椿每,經(jīng)常需要調(diào)用setWebEnvironment(false)

23.7 Accessing application arguments

If you need to access the application arguments that were passed to SpringApplication.run(…?) you can inject a org.springframework.boot.ApplicationArguments bean. The ApplicationArguments interface provides access to both the raw String[] arguments as well as parsed option and non-option arguments:

如果你需要訪問傳進SpringApplication.run(…?)中的應(yīng)用參數(shù)英遭,你可以注入org.springframework.boot.ApplicationArguments bean间护。ApplicationArguments接口提供了訪問原始String[]和轉(zhuǎn)換的optionnon-option參數(shù)挖诸。

import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*

@Component
public class MyBean {

    @Autowired
    public MyBean(ApplicationArguments args) {
        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs();
        // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
    }

}

Spring Boot will also register a CommandLinePropertySource with the Spring Environment. This allows you to also inject single application arguments using the @Value annotation.

?

Spring Boot也在Spring Environment中注冊CommandLinePropertySource汁尺。這也允許你使用@Value注解注入單個應(yīng)對參數(shù)。

23.8 Using the ApplicationRunner or CommandLineRunner

If you need to run some specific code once the SpringApplication has started, you can implement the ApplicationRunner or CommandLineRunner interfaces. Both interfaces work in the same way and offer a single run method which will be called just before SpringApplication.run(…?) completes.

如果你需要在SpringApplication啟動時運行一些特定的代碼多律,你可以實現(xiàn)ApplicationRunnerCommandLineRunner接口痴突。這兩個接口以同樣方式工作,并有一個單獨的run方法狼荞,在SpringApplication.run(…?)之前會調(diào)用這個run方法辽装。

The CommandLineRunner interfaces provides access to application arguments as a simple string array, whereas the ApplicationRunner uses the ApplicationArguments interface discussed above.

CommandLineRunner接口提供了對應(yīng)用參數(shù)的訪問,應(yīng)用參數(shù)作為一個簡單的字符串數(shù)組相味,而ApplicationRunner使用前面描述的ApplicationArguments接口拾积。

import org.springframework.boot.*
import org.springframework.stereotype.*

@Component
public class MyBean implements CommandLineRunner {

    public void run(String... args) {
        // Do something...
    }

}

You can additionally implement the org.springframework.core.Ordered interface or use the org.springframework.core.annotation.Order annotation if several CommandLineRunner or ApplicationRunner beans are defined that must be called in a specific order.

另外,如果定義的CommandLineRunnerApplicationRunner beans必須以指定順序調(diào)用丰涉,你可以實現(xiàn)org.springframework.core.Ordered接口或org.springframework.core.annotation.Order 注解拓巧。

23.9 Application exit

Each SpringApplication will register a shutdown hook with the JVM to ensure that the ApplicationContext is closed gracefully on exit. All the standard Spring lifecycle callbacks (such as the DisposableBean interface, or the @PreDestroy annotation) can be used.

為了確保ApplicationContext在關(guān)閉時安全退出, 每個SpringApplication都會在JVM中注冊一個關(guān)閉鉤子昔搂。所有的標準Spring生命周期回調(diào)函數(shù)(例如DisposableBean接口玲销,或@PreDestroy注解)都會被使用输拇。

In addition, beans may implement the org.springframework.boot.ExitCodeGenerator interface if they wish to return a specific exit code when the application ends.

另外摘符,當應(yīng)用退出時,如果想返回一個指定的退出碼,beans可以實現(xiàn)org.springframework.boot.ExitCodeGenerator接口逛裤。

23.10 Admin features

It is possible to enable admin-related features for the application by specifying the spring.application.admin.enabled property. This exposes the SpringApplicationAdminMXBean on the platform MBeanServer. You could use this feature to administer your Spring Boot application remotely. This could also be useful for any service wrapper implementation.

如果應(yīng)用想啟用admin相關(guān)的功能瘩绒,可以指定spring.application.admin.enabled屬性。這會在平臺MBeanServer上暴露SpringApplicationAdminMXBean带族。你可以使用這個功能遠程的管理你的Spring Boot應(yīng)用锁荔。對于任何服務(wù)包裹的實現(xiàn)這是很有用的。

If you want to know on which HTTP port the application is running, get the property with key local.server.port.

?

如果你想知道應(yīng)用運行的HTTP接口蝙砌,通過關(guān)鍵字local.server.port可以得到這個屬性阳堕。

?

Take care when enabling this feature as the MBean exposes a method to shutdown the application.

?

當啟用這個功能時要非常小心,因為MBean會暴露一個關(guān)閉應(yīng)用的方法择克。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恬总,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肚邢,更是在濱河造成了極大的恐慌壹堰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骡湖,死亡現(xiàn)場離奇詭異贱纠,居然都是意外死亡,警方通過查閱死者的電腦和手機响蕴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門谆焊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浦夷,你說我怎么就攤上這事懊渡。” “怎么了军拟?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵剃执,是天一觀的道長。 經(jīng)常有香客問我懈息,道長肾档,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任辫继,我火速辦了婚禮怒见,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘姑宽。我一直安慰自己遣耍,他們只是感情好,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布炮车。 她就那樣靜靜地躺著舵变,像睡著了一般酣溃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纪隙,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天赊豌,我揣著相機與錄音,去河邊找鬼绵咱。 笑死碘饼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的悲伶。 我是一名探鬼主播艾恼,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼麸锉!你這毒婦竟也來了蒂萎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤淮椰,失蹤者是張志新(化名)和其女友劉穎藤巢,沒想到半個月后巾乳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體士袄,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡堤如,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了忽媒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片争拐。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖晦雨,靈堂內(nèi)的尸體忽然破棺而出架曹,到底是詐尸還是另有隱情,我是刑警寧澤闹瞧,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布绑雄,位于F島的核電站,受9級特大地震影響奥邮,放射性物質(zhì)發(fā)生泄漏万牺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一洽腺、第九天 我趴在偏房一處隱蔽的房頂上張望脚粟。 院中可真熱鬧,春花似錦蘸朋、人聲如沸核无。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽团南。三九已至噪沙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間已慢,已是汗流浹背曲聂。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工霹购, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留佑惠,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓齐疙,卻偏偏與公主長得像膜楷,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子贞奋,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

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