SpringBoot

springboot 概述

SpringBoot能夠快速開發,簡化部署,適用于微服務

參考嘟嘟大神SpringBoot系列

1. 什么是SpringBoot??

SpringBoot是一個基于Spring4而產生的一個微框架;Spring Boot并不是要成為Spring IO平臺里面眾多“Foundation”層項目的替代者。Spring Boot的目標不在于為已解決的問題域提供新的解決方案,而是為平臺帶來另一種開發體驗,從而簡化對這些已有技術的使用。對于已經熟悉Spring生態系統的開發人員來說,Boot是一個很理想的選擇,不過對于采用Spring技術的新人來說,Boot提供一種更簡潔的方式來使用這些技術;SpringBoot也是使用微服務架構的最好選擇。

SpringBoot能解決那些問題?

SpringBoot使編碼更簡單,使配置更簡單,使部署更簡單,使監控更簡單

2.SpringBoot 精要

Spring將很多魔法帶入了Spring應用程序的開發之中,其中最重要的是以下四個核心。

自動配置:針對很多Spring應用程序常見的應用功能,Spring Boot能自動提供相關配置

起步依賴:告訴Spring Boot需要什么功能,它就能引入需要的庫。

命令行界面:這是Spring Boot的可選特性,借此你只需寫代碼就能完成完整的應用程序,無需傳統項目構建。

Actuator:讓你能夠深入運行中的Spring Boot應用程序,一探究竟。

3.SpringBoot能帶給我們什么?

從字面意思理解,Boot是引導,SpringBoot能夠幫助開發者快速搭建Spring框架;

SpringBoot能夠幫助開發者快速啟動一個Web容器;

SpringBoot繼承了Spring框架的原有優秀基因;

SpringBoot簡化了Spring的開發過程;

SpringBoot更多的是使用了Java Config的方式,對Spring進行配置;

SpringBoot更是一個微服務的起點。


配置文件的優先級

application.properties和application.yml文件可以放在以下四個位置(優先級由高到低):

外置,在相對于應用程序運行目錄的/congfig子目錄里。

外置,在應用程序運行的目錄里

內置,在config包內

內置,在Classpath根目錄

同樣,這個列表按照優先級排序,也就是說,src/main/resources/config下application.properties覆蓋src/main/resources下application.properties中相同的屬性,如圖:

配置文件

此外,如果你在相同優先級位置同時有application.properties和application.yml,那么application.properties里的屬性里面的屬性就會覆蓋application.yml。

Profile-多環境配置

在Spring Boot中多環境配置文件名需要滿足application-{profile}.properties的格式(或者.yml),其中{profile}對應你的環境標識,比如:

application-dev.properties:開發環境

application-pro.properties:生產環境

想要使用對應的環境,只需要在application.properties中使用spring.profiles.active屬性來設置,值對應上面提到的{profile},這里就是指dev、prod這2個。除了spring.profiles.active來激活一個或者多個profile之外,還可以用spring.profiles.include來疊加profile

spring.profiles.active: dev

spring.profiles.include: prodb,promq

除了可以用profile的配置文件來分區配置我們的環境變量,在代碼里,我們還可以直接用@Profile注解來進行配置

啟動原理解析

SpringBoot的啟動類會用到@SpringBootApplication這個注解

@SpringBootApplication由以下三個注解組成:

@Configuration(@SpringBootConfiguration點開查看發現里面還是應用了@Configuration)

@EnableAutoConfiguration

@ComponentScan

?@Configuration

@Configuration就是JavaConfig形式的Spring Ioc容器的配置類使用的那個@Configuration,SpringBoot社區推薦使用基于JavaConfig的配置形式,所以,這里的啟動類標注了@Configuration之后,本身其實也是一個IoC容器的配置類。

XML跟config配置方式的區別:

@Configuration
@Bean
Bean之間的依賴

@ComponentScan

@ComponentScan這個注解在Spring中很重要,它對應XML配置中的元素,@ComponentScan的功能其實就是自動掃描并加載符合條件的組件(比如@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。

我們可以通過basePackages等屬性來細粒度的定制@ComponentScan自動掃描的范圍,如果不指定,則默認Spring框架實現會從聲明@ComponentScan所在類的package進行掃描。

注:所以SpringBoot的啟動類最好是放在root package下,因為默認不指定basePackages。

@EnableAutoConfiguration

@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和做事方式其實一脈相承,簡單概括一下就是,借助@Import的支持,收集和注冊特定場景相關的bean定義

@EnableScheduling是通過@Import將Spring調度框架相關的bean定義都加載到IoC容器。

@EnableMBeanExport是通過@Import將JMX相關的bean定義加載到IoC容器。

而@EnableAutoConfiguration也是借助@Import的幫助,將所有符合自動配置條件的bean定義加載到IoC容器,僅此而已!



SpringFactoriesLoader從指定的配置文件META-INF/spring.factories加載配置。配合@EnableAutoConfiguration使用的話,它更多是提供一種配置查找的功能支持,即根據@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration作為查找的Key,獲取對應的一組@Configuration類。? ?

所以,@EnableAutoConfiguration自動配置的魔法騎士就變成了:從classpath中搜尋所有的META-INF/spring.factories配置文件,并將其中org.springframework.boot.autoconfigure.EnableutoConfiguration對應的配置項通過反射(Java Refletion)實例化為對應的標注了@Configuration的JavaConfig形式的IoC容器配置類,然后匯總為一個并加載到IoC容器。


SpringApplication執行流程

SpringApplication的run方法的主要流程大體可以歸納如下:

1) 如果我們使用的是SpringApplication的靜態run方法,那么,這個方法里面首先要創建一個SpringApplication對象實例,然后調用這個創建好的SpringApplication的實例方法。在SpringApplication實例初始化的時候,它會提前做幾件事情:

根據classpath里面是否存在某個特征類(org.springframework.web.context.ConfigurableWebApplicationContext)來決定是否應該創建一個為Web應用使用的ApplicationContext類型。

使用SpringFactoriesLoader在應用的classpath中查找并加載所有可用的ApplicationContextInitializer。

使用SpringFactoriesLoader在應用的classpath中查找并加載所有可用的ApplicationListener。

推斷并設置main方法的定義類。

2) SpringApplication實例初始化完成并且完成設置后,就開始執行run方法的邏輯了,方法執行伊始,首先遍歷執行所有通過SpringFactoriesLoader可以查找到并加載的SpringApplicationRunListener。調用它們的started()方法,告訴這些SpringApplicationRunListener,“嘿,SpringBoot應用要開始執行咯!”。

3) 創建并配置當前Spring Boot應用將要使用的Environment(包括配置要使用的PropertySource以及Profile)。

4) 遍歷調用所有SpringApplicationRunListener的environmentPrepared()的方法,告訴他們:“當前SpringBoot應用使用的Environment準備好了咯!”。

5) 如果SpringApplication的showBanner屬性被設置為true,則打印banner。

6) 根據用戶是否明確設置了applicationContextClass類型以及初始化階段的推斷結果,決定該為當前SpringBoot應用創建什么類型的ApplicationContext并創建完成,然后根據條件決定是否添加ShutdownHook,決定是否使用自定義的BeanNameGenerator,決定是否使用自定義的ResourceLoader,當然,最重要的,將之前準備好的Environment設置給創建好的ApplicationContext使用。

7) ApplicationContext創建好之后,SpringApplication會再次借助Spring-FactoriesLoader,查找并加載classpath中所有可用的ApplicationContext-Initializer,然后遍歷調用這些ApplicationContextInitializer的initialize(applicationContext)方法來對已經創建好的ApplicationContext進行進一步的處理。

8) 遍歷調用所有SpringApplicationRunListener的contextPrepared()方法。

9) 最核心的一步,將之前通過@EnableAutoConfiguration獲取的所有配置以及其他形式的IoC容器配置加載到已經準備完畢的ApplicationContext。

10) 遍歷調用所有SpringApplicationRunListener的contextLoaded()方法。

11) 調用ApplicationContext的refresh()方法,完成IoC容器可用的最后一道工序。

12) 查找當前ApplicationContext中是否注冊有CommandLineRunner,如果有,則遍歷執行它們。

13) 正常情況下,遍歷執行SpringApplicationRunListener的finished()方法、(如果整個過程出現異常,則依然調用所有SpringApplicationRunListener的finished()方法,只不過這種情況下會將異常信息一并傳入處理)


Spring MVC自動配置

Spring Boot為Spring MVC提供適用于多數應用的自動配置功能。在Spring默認基礎上,自動配置添加了以下特性:

1)引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。

2)對靜態資源的支持,包括對WebJars的支持。

3)自動注冊Converter,GenericConverter,Formatter beans。

4)對HttpMessageConverters的支持。

5)自動注冊MessageCodeResolver。

6)對靜態index.html的支持。

7)對自定義Favicon的支持。

如果想全面控制Spring MVC,你可以添加自己的@Configuration,并使用@EnableWebMvc對其注解。如果想保留Spring Boot MVC的特性,并只是添加其他的MVC配置(攔截器,formatters,視圖控制器等),你可以添加自己的WebMvcConfigurerAdapter類型的@Bean(不使用@EnableWebMvc注解)


默認資源映射

Spring Boot 默認為我們提供了靜態資源處理,使用 WebMvcAutoConfiguration 中的配置各種屬性。

建議大家使用Spring Boot的默認配置方式,提供的靜態資源映射如下(優先級由高到低):

classpath:/META-INF/resources

classpath:/resources

classpath:/static

classpath:/public

靜態資源映射

可以在上面4個路徑下都放一張同名的圖片,訪問一下即可驗證。

任意在上面一個路徑下面放上index.html,當訪問應用根目錄http://lcoalhost:8080時,會直接映射到index.html頁面。

對應的配置文件配置如下:

# 默認值為 /**

spring.mvc.static-path-pattern=

# 默認值為 classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/

spring.resources.static-locations=這里設置要指向的路徑,多個使用英文逗號隔開

我們可以通過修改spring.mvc.static-path-pattern來修改默認的映射,例如我改成/dudu/**,那運行的時候訪問?http://lcoalhost:8080/dudu/index.html?才對應到index.html頁面。

自定義資源映射addResourceHandlers

如果Spring Boot提供的Sping MVC不符合要求,則可以通過一個配置類(注解有@Configuration的類)加上@EnableWebMvc注解來實現完全自己控制的MVC配置。

當然,通常情況下,Spring Boot的自動配置是符合我們大多數需求的。在你既需要保留Spring Boot提供的便利,有需要增加自己的額外的配置的時候,可以定義一個配置類并繼承WebMvcConfigurerAdapter,無需使用@EnableWebMvc注解。

比如,我們想自定義靜態資源映射目錄的話,只需重寫addResourceHandlers方法即可。

自定義靜態資源映射目錄

通過addResourceHandler添加映射路徑,然后通過addResourceLocations來指定路徑。我們訪問自定義my文件夾中的elephant.jpg 圖片的地址為?http://localhost:8080/my/elephant.jpg

如果想指定外部的目錄也很簡單,直接addResourceLocations指定即可,代碼如下:

指定外部目錄

攔截器addInterceptors

要實現攔截器功能需要完成以下2個步驟:

1.創建我們自己的攔截器類并實現 HandlerInterceptor 接口

2.重寫WebMvcConfigurerAdapter中的addInterceptors方法把自定義的攔截器類添加進

首先,自定義攔截器代碼:

自定義攔截器

接著,重寫WebMvcConfigurerAdapter中的addInterceptors方法如下:

攔截器


默認日志Logback

Logback是log4j框架的作者開發的新一代日志框架,它效率更高、能夠適應諸多的運行環境,同時天然支持SLF4J。

假如maven依賴中添加了spring-boot-starter-logging:

Logback依賴

那么,我們的Spring Boot應用將自動使用logback作為應用日志框架

(但是呢,實際開發中我們不需要直接添加該依賴,你會發現spring-boot-starter其中包含了 spring-boot-starter-logging,該依賴內容就是 Spring Boot 默認的日志框架 logback。而Thymeleaf依賴包含了spring-boot-starter,最終我只要引入Thymeleaf即可)

文件輸出

默認情況下,Spring Boot將日志輸出到控制臺,不會寫到日志文件。如果要編寫除控制臺輸出之外的日志文件,則需在application.properties中設置logging.file或logging.path屬性。

logging.file,設置文件,可以是絕對路徑,也可以是相對路徑。如:logging.file=my.log

logging.path,設置目錄,會在該目錄下創建spring.log文件,并寫入日志內容,如:logging.path=/var/log

如果只配置 logging.file,會在項目的當前路徑下生成一個 xxx.log 日志文件。

如果只配置 logging.path,在 /var/log文件夾生成一個日志文件為 spring.log

注:二者不能同時使用,如若同時使用,則只有logging.file生效


JdbcTemplate的使用

這里需要添加spring-boot-starter-jdbc依賴跟mysql依賴

添加依賴


在src/main/resources/application.properties中配置數據源信息。

配置數據源


Spring的JdbcTemplate是自動配置的,你可以直接使用@Autowired來注入到你自己的bean中來使用。

在dao層的實現類,注入我們需要的JdbcTemplate。

注入JdbcTemplate


MyBatis的使用

添加mybatis-spring-boot-starter依賴跟mysql依賴,mybatis-spring-boot-starter中已經包含了Jdbc依賴

引入依賴

MyBatis-Spring-Boot-Starter依賴將會提供如下:

自動檢測現有的DataSource

將創建并注冊SqlSessionFactory的實例,該實例使用SqlSessionFactoryBean將該DataSource作為輸入進行傳遞

將創建并注冊從SqlSessionFactory中獲取的SqlSessionTemplate的實例。

自動掃描您的mappers,將它們鏈接到SqlSessionTemplate并將其注冊到Spring上下文,以便將它們注入到您的bean中。

就是說,使用了該Starter之后,只需要定義一個DataSource即可(application.properties中可配置),它會自動創建使用該DataSource的SqlSessionFactoryBean以及SqlSessionTemplate。會自動掃描你的Mappers,連接到SqlSessionTemplate,并注冊到Spring上下文中。

注解方式(xml方式省略)

Mybatis注解的方式好簡單,只要定義一個dao接口,然后sql語句通過注解寫在接口方法上。最后給這個接口添加@Mapper注解或者在啟動類上添加@MapperScan(“com.dudu.dao”)注解都行。

dao層使用注解方式
@DeleteProvider方法補全

這些可選的 SQL 注解允許你指定一個類名和一個方法在執行時來返回運行 允許創建動態 的 SQL。 基于執行的映射語句, MyBatis 會實例化這個類,然后執行由 provider 指定的方法. 該方法可以有選擇地接受參數對象.(In MyBatis 3.4 or later, it’s allow multiple parameters) 屬性: type,method。type 屬性是類。method 屬性是方法名。 注意: 這節之后是對 類的 討論,它可以幫助你以干凈,容于閱讀 的方式來構建動態 SQL。

通用Mapper插件

引入了mybatis相關的一些依賴以及generator的配置,這里generator配置文件指向src/main/resources/mybatis-generator.xml文件,mybatis-generator.xml文件用來自動生成表對應的Model,Mapper以及xml,一會兒會提到。(Mybatis Geneator 詳解

mybatis-generator.xml文件

通用Mapper都可以極大的方便開發人員,對單表封裝了許多通用方法,省掉自己寫增刪改查的sql。(通用Mapper插件網址)

對應的application.properties配置:

配置文件

這里實現一個自己的接口,繼承通用的mapper,關鍵點就是這個接口不能被掃描到,mapper接口不能放在dao包里。

最后在啟動類中通過MapperScan注解指定掃描的mapper路徑(dao)

定義mapper接口

IDEA自動生成文件的方法:

自動生成文件

根據mybatis-generator.xml文件,自動生成model,mapper,xml文件

自動生成的文件

MyBatis分頁插件

物理分頁插件pagehelper,引入依賴

pom中添加依賴


只需在查詢list之前使用PageHelper.startPage(int pageNum, int pageSize)方法即可。pageNum是第幾頁,pageSize是每頁多少條。

(Service層的實現類) 進行分頁查詢

業務邏輯層(service)的實現

正常情況下具體業務是每個模塊的service里面定義許多方法,然后mapper中實現。

但通用Mapper在Spring4中的最佳用法是通用的Service(具體了解

定義一個通用接口:

定義通用接口

具體實現通用接口類

實現通用接口

到此基本的增刪改查通用service就寫好了,具體業務的service就直接繼承這個接口即可,也可以添加額外的方法

具體的service

具體實現service(實現類extends BaseService),然后再mapper文件中(我覺得相當于dao)實現sevice自定義的方法。

mapper實現具體方法

在自動生成的xml文件中實現具體方法(相當于dao的實現類):

Mapper.xml


Spring Loaded 實現熱部署

Spring Loaded是一個用于在JVM運行時重新加載類文件更改的JVM代理,Spring Loaded允許你動態的新增/修改/刪除某個方法/字段/構造方法,同樣可以修改作用在類/方法/字段/構造方法上的注解.也可以新增/刪除/改變枚舉中的值。

Spring Loaded有兩種方式實現,分別是Maven引入依賴方式或者添加啟動參數方式

Maven依賴方式

Maven依賴方式

如果用IDEA也可以這樣啟動

idea啟動

注意:maven依賴的方式只適合spring-boot:run的啟動方式,右鍵那種方式不行。

出現這個說明配置成功

[INFO] Attaching agents: [C:\Users\tengj\.m2\repository\org\springframework\springloaded\1.2.6.RELEASE\springloaded-1.2.6.RELEASE.jar]

還有種方式是右鍵運行啟動類

首先先下載對應的springloaded-1.2.6.RELEASE.jar,可以去上面提到的官網獲取(這里直接引用maven依賴已經下載好的路徑)

然后打開下圖所示的Edit Configurations配置,在VM options中輸入:

-javaagent:C:\Users\tengj\.m2\repository\org\springframework\springloaded\1.2.6.RELEASE\springloaded-1.2.6.RELEASE.jar -noverify

上面2種方式隨便選擇一種即可,當系統通過 mvn spring-boot:run啟動或者 右鍵application debug啟動Java文件時,系統會監視classes文件,當有classes文件被改動時,系統會重新加載類文件,不用重啟啟動服務。(注:IDEA下需要重新編譯文件 Ctrl+Shift+F9或者編譯項目 Ctrl+F9 )

還可以使用spring-boot-devtools 方式、JRebel插件方式實現熱部署

經過簡單的測試,發現大多數情況可以使用熱部署,不過還是有一些情況下需要重新啟動,不可用的情況如下:

1:對于一些第三方框架的注解的修改,不能自動加載,比如:spring mvc的@RequestMapping?

2:application.properties的修改也不行?

3:log4j的配置文件的修改不能即時生


單元測試

Spring Boot中單元測試類寫在在src/test/java目錄下,你可以手動創建具體測試類,如果是IDEA,則可以通過IDEA自動創建測試類

最簡單的單元測試寫法(Service層),頂部只要@RunWith(SpringRunner.class)和SpringBootTest即可,想要執行的時候,鼠標放在對應的方法,右鍵選擇run該方法即可。推薦大家使用該assertThat斷言。

有時候需要對Controller層(API)做測試,這時候就得用到MockMvc了,你可以不必啟動工程就能測試這些接口。MockMvc實現了對Http請求的模擬,能夠直接使用網絡的形式,轉換到Controller的調用,這樣可以使得測試速度快、不依賴網絡環境,而且提供了一套驗證的工具,這樣可以使得請求的驗證統一而且很方便。

使用MockMvc的時候需要先用MockMvcBuilders使用構建MockMvc對象,如下

創建MockMvc對象

MockMvc簡單的方法

使用MoxkMvc進行測試

1. mockMvc.perform執行一個請求

2. MockMvcRequestBuilders.get(“/user/1”)構造一個請求,Post請求就用.post方法

3. contentType(MediaType.APPLICATION_JSON_UTF8)代表發送端發送的數據格式是application/json;charset=UTF-8

4. accept(MediaType.APPLICATION_JSON_UTF8)代表客戶端希望接受的數據類型為application/json;charset=UTF-8

5. session(session)注入一個session,這樣攔截器才可以通過

6. ResultActions.andExpect添加執行完成后的斷言

7. ResultActions.andExpect(MockMvcResultMatchers.status().isOk())方法看請求的狀態響應碼是否為200如果不是則拋異常,測試不通過

8. andExpect(MockMvcResultMatchers.jsonPath(“$.author”).value(“嘟嘟MD獨立博客”))這里jsonPath用來獲取author字段比對是否為嘟嘟? ? ? MD獨立博客,不是就測試不通過

9. ResultActions.andDo添加一個結果處理器,表示要對結果做點什么事情,比如此處使用MockMvcResultHandlers.print()輸出整個響應結果信息

新斷言assertThat使用

JUnit 4.4 結合 Hamcrest 提供了一個全新的斷言語法——assertThat。只使用 assertThat 一個斷言語句,結合 Hamcrest 提供的匹配符,就可以表達全部的測試思想,。 JUnit 4.4 默認提供一些可讀的描述性錯誤信息

使用asserThat的兩個例子:

1.? assertThat( [value], [matcher statement] );

2.? assertThat(s, anyOf(containsString("a"), containsString("b")));? ? //表示s里面是否包含“”“a”或者“”“b”

單元測試回滾

單元個測試的時候如果不想造成垃圾數據,可以開啟事物功能,記在方法或者類頭部添加@Transactional注解即可,如下:

測試回滾

這樣測試完數據就會回滾了,不會造成垃圾數據。如果想關閉回滾,只要加上@Rollback(false)注解即可。傳入一個參數value,默認true即回滾,false不回滾。如果你使用的數據庫是Mysql,有時候會發現加了注解@Transactional?也不會回滾,那么你就要查看一下你的默認引擎是不是InnoDB,如果不是就要改成InnoDB,如下圖:

修改引擎


微服務

微服務是一種細粒度的SOA(面向服務架構)

SOA特性: 面向服務? ?松耦合? 模塊化? ?分布式計算? 平臺無關性? ?集中管理

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

推薦閱讀更多精彩內容