Spring Boot 第二彈比庄,配置文件詳解-史上最全

"Madison龍少"

往期文章回顧: Spring Boot 第一彈,問候一下世界=咸场S≌帷扒最!

前言

?上彈說到如何使用Spring Boot問候一下世界丑勤,想必大家都對Spring Boot已經(jīng)有一定的掌握了。如果還沒看的吧趣,沒關(guān)系法竞,可以點擊上面往期回顧鏈接前去學(xué)習耙厚。

?今天我們一起來學(xué)習Spring Boot第二彈,玩轉(zhuǎn)Spring Boot配置文件岔霸。

?說起Spring Boot的配置文件薛躬,真的是愛恨交加,相對于之前Spring大量的配置文件呆细,現(xiàn)在的Spring Boot簡直簡直簡直型宝。。絮爷。,怎一個爽字了得趴酣。當然了,爽的同時坑夯,也迎來了不少困擾岖寞,比如:我們對于Spring Boot是如何實現(xiàn)的只需要修改配置文件就能達到一定效果也是充滿了好奇,這個就需要我們?nèi)ラ喿xSpring Boot的源碼-自動裝配原理了柜蜈,仗谆。這里我就不再贅述了,后面我會出專門針對源碼進行分析的文章,敬請期待吧!!!

話不多說淑履,開搞!!!

Spring Boot配置文件格式

?Spring Boot 官方提供了兩種常用的配置文件格式隶垮,分別是propertiesYML格式秘噪。相比于properties來說岁疼,YML更加年輕,層級也是更加分明缆娃。強烈推薦使用YML格式

Spring Boot配置文件優(yōu)先級加載機制

?Spring Boot項目啟動會掃描以下位置的application.properties或者application.yml作為默認的配置文件.

  1. file:./config/
  2. file:./config/*/
  3. file:./
  4. classpath:/config/
  5. classpath:/

?加載的優(yōu)先級順序是從上向下加載捷绒,并且所有的文件都會被加載高優(yōu)先級的內(nèi)容會覆蓋低優(yōu)先級的內(nèi)容贯要,形成互補配置

徒手撕源碼

?我們可以從ConfigFileApplicationListener這個類中找到暖侨,其中DEFAULT_SEARCH_LOCATIONS屬性設(shè)置了加載的目錄:

public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
    private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/";
    private static final String DEFAULT_NAMES = "application";
    private static final Set<String> NO_SEARCH_NAMES = Collections.singleton((Object)null);
    private static final Bindable<String[]> STRING_ARRAY = Bindable.of(String[].class);
    private static final Bindable<List<String>> STRING_LIST = Bindable.listOf(String.class);
    private static final Set<String> LOAD_FILTERED_PROPERTY;
    public static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active";
    public static final String INCLUDE_PROFILES_PROPERTY = "spring.profiles.include";
    public static final String CONFIG_NAME_PROPERTY = "spring.config.name";
    public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";
    public static final String CONFIG_ADDITIONAL_LOCATION_PROPERTY = "spring.config.additional-location";
                                          ...
                                          ...
                                          ...
}

?然后在ConfigFileApplicationListener類中的getSearchLocations方法中去逗號解析成Set,其中內(nèi)部類Loader負責這一配置文件的加載過程崇渗,包括加載profile指定環(huán)境的配置字逗,以application+’-’+name格式的拼接加載。

內(nèi)部類Loader的load方法

private void load(ConfigFileApplicationListener.Profile profile, ConfigFileApplicationListener.DocumentFilterFactory filterFactory, ConfigFileApplicationListener.DocumentConsumer consumer) {
    this.getSearchLocations().forEach((location) -> {
        String nonOptionalLocation = ConfigDataLocation.of(location).getValue();
        boolean isDirectory = location.endsWith("/");
        Set<String> names = isDirectory ? this.getSearchNames() : ConfigFileApplicationListener.NO_SEARCH_NAMES;
        names.forEach((name) -> {
            this.load(nonOptionalLocation, name, profile, filterFactory, consumer);
        });
    });
}

getSearchLocations()方法

private Set<String> getSearchLocations() {
    Set<String> locations = this.getSearchLocations("spring.config.additional-location");
    if (this.environment.containsProperty("spring.config.location")) {
        locations.addAll(this.getSearchLocations("spring.config.location"));
    } else {
        locations.addAll(this.asResolvedSet(ConfigFileApplicationListener.this.searchLocations, "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/"));
    }

    return locations;
}

asResolvedSet()

private Set<String> asResolvedSet(String value, String fallback) {
    List<String> list = Arrays.asList(StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(value != null ? this.environment.resolvePlaceholders(value) : fallback)));
    Collections.reverse(list);
    return new LinkedHashSet(list);
}

?其實可以看出源碼里面給出的配置文件排列順序跟加載順序是相反的宅广。而是使用了Collections.reverse(list)方法

  • 我們也可以通過指定配置spring.config.location來改變默認配置葫掉,一般在項目已經(jīng)打包后,我們可以通過以下指令來加載外部的配置跟狱。
java -jar XXX-0.0.1-SNAPSHOT.jar --spring.config.location=F:/application.yml
  • 另外也可以通過命令行參數(shù)進行配置

    ???所有的配置都可以在命令行上進行指定

    ???多個配置用空格分開俭厚;--配置項=值
java -jar XXX-0.0.1-SNAPSHOT.jar 
--server.port=8888 --server.context-path=/qlh

下面給出優(yōu)先級從高到低的配置文件排列順序:

  • 命令行參數(shù)
  • 來自java:comp/env的JNDI屬性
  • Java系統(tǒng)屬性(System.getProperties())
  • 操作系統(tǒng)環(huán)境變量
  • RandomValuePropertySource配置的random.*屬性值

    備注:由jar包外向jar包內(nèi)進行尋找,優(yōu)先加載帶profile的驶臊,再加載不帶profile的
  • jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配- 置文件
  • jar包內(nèi)部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
  • jar包外部的application.properties或application.yml(不帶spring.profile)配置文件
  • jar包內(nèi)部的application.properties或application.yml(不帶spring.profile)配置文件
  • @Configuration注解類上的@PropertySource
  • 通過SpringApplication.setDefaultProperties指定的默認屬性

properties挪挤、YAML配置優(yōu)先級加載機制

?Spring Boot使用一個以application命名的配置文件作為默認的全局配置文件叼丑。支持properties后綴結(jié)尾的配置文件或者以yml/yaml后綴結(jié)尾的YAML的文件配置。

以設(shè)置應(yīng)用端口為例初體驗Spring Boot配置文件

properties后綴結(jié)尾(application.properties)

server.port=80

yml/yaml后綴結(jié)尾(application.yml/application.yaml)

server:
  prot: 8088

注:同一目錄下扛门,properties配置文件優(yōu)先級 > yml/yaml配置文件優(yōu)先級鸠信。因此在jar包啟動時如果帶上properties寫法的配置可以覆蓋配置。

yaml/yml配置文件寫法冒號后要加空格

properties配置文件

語法結(jié)構(gòu)為:key=value

值類型:

數(shù)字论寨,字符串星立,布爾,日期

person.name=tinygrey
person.age=18
person.status=true
person.birthday=2020/11/23

對象葬凳、Map

#Map
person.assets.phone=iphone 12
person.assets.car=捷豹
#對象
person.dog.name=奶狗
person.dog.age=3

數(shù)組

person.hobby[0]=打籃球
person.hobby[1]=睡覺
person.hobby[2]=玩游戲
person.hobby[3]=學(xué)習

yml/yaml配置文件

?以空格的縮進程度來控制層級關(guān)系贞铣。空格的個數(shù)并不重要沮明,只要左邊空格對齊則視為同一個層級辕坝。注意不能用tab代替空格。且大小寫敏感荐健。支持字面值酱畅,對象,數(shù)組三種數(shù)據(jù)結(jié)構(gòu)江场,也支持復(fù)合 結(jié)構(gòu)纺酸。

?字面值字符串布爾類型址否,數(shù)值餐蔬,日期。字符串默認不加引號佑附,單引號會轉(zhuǎn)義特殊字符樊诺。日期格式支持yyyy/MM/dd HH:mm:ss

?對象:由鍵值對組成,形如 key:(空格)value 的數(shù)據(jù)組成音同。冒號后面的空格是必須要有的词爬,每組鍵值對占用一行,且縮進的程度要一致权均,也可以使用行內(nèi)寫法{k1: v1, ....kn: vn}

?數(shù)組:由形如 -(空格)value 的數(shù)據(jù)組成顿膨。短橫線后面的空格是必須要有的,每組數(shù)據(jù)占用一行叽赊,且縮進的程度要一致恋沃,也可以使用行內(nèi)寫法:[1,2,...n]

復(fù)合結(jié)構(gòu):上面三種數(shù)據(jù)結(jié)構(gòu)任意組合

值類型:

數(shù)字,字符串必指,布爾囊咏,日期

person:
  name: tinygrey
  age: 18
  status: true
  birthday: 2002/04/02

對象、Map

person:
  #Map
  assets:
    phone: iphone 12
    car: 捷豹
  #對象
  dog:
    name: 奶狗
    age: 3
#行內(nèi)寫法
person:
  #Map
  assets: {phone: iphone 12,car: 捷豹}
  #對象
  dog: {name: 奶狗,age: 3}

數(shù)組

person:
  hobby:
    - 打籃球
    - 睡覺
    - 玩游戲
    - 學(xué)習
#行內(nèi)寫法
person:
  hobby: [打籃球,睡覺,玩游戲,學(xué)習]

注:YML是一種新式的格式,層級鮮明匆笤,強烈推薦使用研侣。

注意如下::

?字符串可以不加引號谱邪,若加雙引號則輸出特殊字符炮捧,若不加或加單引號則轉(zhuǎn)義特殊字符

?數(shù)組類型,短橫線后面要有空格惦银;對象類型咆课,冒號后面要有空格

?yaml/yml是以空格縮進的程度來控制層級關(guān)系,但不能用tab鍵代替空格扯俱,大小寫敏感

本文所有提到的配置文件都對應(yīng)下面實體類做為參考

@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@Component
@PropertySource(value = "classpath:config/custom-profile.properties", encoding = "utf-8")
@ConfigurationProperties(prefix = "person")
public class Person {
    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private int age;
    private boolean status;
    @Value("${person.birthday}")
    private Date birthday;
    private List<String> hobby;
    private Map<String, Object> assets;
    private Dog dog;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@Component
@PropertySource(value = "classpath:config/custom-profile.properties", encoding = "utf-8")
@ConfigurationProperties(prefix = "dog")
class Dog {
    private String name;
    private Integer age;
}

配置文件如何跟實體類綁定

Spring Boot一切的配置都是為了取值书蚪,Spring Boot提供了一些取值的方式。我們一起來看一下迅栅。

@ConfigurationProperties(prefix = "person")詳解

注: 該注解用于從配置文件中取值殊校,支持復(fù)雜的數(shù)據(jù)類型,但是不支持SPEL表達式登澜。

prefix屬性:指定獲配置的前綴眠菇,畢竟配置文件中的屬性很多烫映,也有很多重名的,必須用一個前綴來區(qū)分下敬察。

該注解可以標注在類上也可以標注在方法上,這里就可以看出它有兩種獲取值的方式尔当。

標注在類上

@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@Component //注入到IOC容器中
@ConfigurationProperties(prefix = "person")//從配置文件中讀取文件
public class Person {
    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private int age;
    @Value("${person.birthday}")
    private Date birthday;
    private List<String> hobby;
    private Map<String, Object> assets;
    private Dog dog;
}

標注在方法上

/**
 * @Bean 將返回的結(jié)果注入到IOC容器中
 * @ConfigurationProperties 從配置文件中取值
 * @return
 */
@ConfigurationProperties(prefix = "person")
@Bean
public Person person(){
    return new Person();
}

綜上所述

?@ConfigurationProperties注解能夠輕松的讓配置文件跟實體類綁定在一起莲祸。

具有以下優(yōu)點:

  • 注入屬性支持批量,僅僅指定一個前綴prefix即可
  • 數(shù)據(jù)類型支持復(fù)雜數(shù)據(jù)椭迎,比如List锐帜、Map
  • 屬性名匹配規(guī)則-松散綁定,比如a-b畜号,a_b抹估,aBA_B都可以取值
  • 支持JAVA的JSR303數(shù)據(jù)校驗

?值得關(guān)注的是:@ConfigurationProperties這個注解僅僅是支持從Spring Boot的默認配置文件中取值弄兜,也就是application.properties药蜻、application.ymlapplication.yaml替饿,那我們?nèi)绾螐淖远x配置文件取值呢语泽??视卢?

?別著急踱卵,有解決辦法,那就是再加一個注解:@PropertySource(value = "classpath:custom-profile.properties"),下面會有對@PropertySource注解的介紹。請耐心往下面看惋砂。

@Value

?@Value這個注解我們應(yīng)該都比較熟悉了妒挎,Spring中從屬性取值的注解,支持SPEL表達式西饵,不支持復(fù)雜的數(shù)據(jù)類型酝掩,比如Map、List眷柔。使用可以參考上面實體類里面的代碼期虾。

自定義配置文件并取值

?Spring Boot在啟動的時候會自動加載application.xxx,但是有的時候為了避免application.xxx配置文件過于臃腫,就需要我們自定義配置文件驯嘱,那么自定義配置文件的話镶苞,我們?nèi)绾螐淖远x配置文件里面取值呢?這時候就需要配合@PropertySource這個注解使用了鞠评。

使用@PropertySource注解

?在配置類上標注@PropertySource并指定你自定義的配置文件即可茂蚓。可以參考下面代碼

@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@Component
@PropertySource(value = {"classpath:config/custom-profile.properties"}, encoding = "utf-8")
@ConfigurationProperties(prefix = "person")
public class Person {
    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private int age;
    @Value("${person.birthday}")
    private Date birthday;
    private List<String> hobby;
    private Map<String, Object> assets;
    private Dog dog;
}

對應(yīng)配置文件

person.name=tinygrey
person.age=18
person.birthday=2020/11/23
person.hobby[0]=打籃球
person.hobby[1]=睡覺
person.hobby[2]=玩游戲
person.hobby[3]=學(xué)習
person.assets.phone=iphone 12
person.assets.car=捷豹
person.dog.name=奶狗
person.dog.age=3

@PropertySource注解屬性

value:是一個數(shù)組剃幌,可以指定多個配置文件同時引入聋涨。

??value是數(shù)組那么問題就來了:如果同時加載多個配置文件,并且不同配置文件中對同一個屬性設(shè)置了不同的值锥忿,那么Spring會識別哪一個呢?

創(chuàng)建兩個配置文件custom-profile.yml牛郑、custom-profile1.yml,如下去引入敬鬓。

@PropertySource(value = {"classpath:config/custom-profile.yml","classpath:config/custom-profile1.yml"})
public class Person {
...
}

我們可以通過控制變量法進行測試淹朋,具體過程我這里就不贅述了。

直接說結(jié)論吧:Spring加載順序從左到右順序加載钉答,后加載的會覆蓋先加載的屬性值础芍。

另外需要注意的是@PropertySource默認加載xxx.properties類型的配置文件,不能加載YML格式的配置文件数尿。如何解決呢仑性?下面來解決這一問題

加載自定義YML格式的配置文件

?@PropertySource注解有一個屬性factory,默認值是PropertySourceFactory.class右蹦,這個就是用來加載properties格式的配置文件诊杆,那我們自定義一個用來加載YML格式的配置文件不就可以了嘛?上代碼

/**
 * 解決@PropertySource只對properties文件可以進行加載何陆,但對于yml或者yaml不能支持晨汹。
 */
public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        String sourceName = name != null ? name : resource.getResource().getFilename();
        if (!resource.getResource().exists()) {
            assert sourceName != null;
            return new PropertiesPropertySource(sourceName, new Properties());
        } else if (Objects.requireNonNull(sourceName).endsWith(".yml") || sourceName.endsWith(".yaml")) {
            Properties propertiesFromYaml = loadYamlProperties(resource);
            return new PropertiesPropertySource(sourceName, propertiesFromYaml);
        } else {
            return super.createPropertySource(name, resource);
        }
    }

    private Properties loadYamlProperties(EncodedResource resource){
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}

?我們寫好上面的代碼之后,只需要添加@PropertySource注解中factory屬性指定為YmlPropertySourceFactory即可,代碼如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
@Component
@PropertySource(value = {"classpath:config/custom-profile.yml"}, encoding = "utf-8", factory = YmlPropertySourceFactory.class)
@ConfigurationProperties(prefix = "person")
public class Person {
    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private int age;
    @Value("${person.birthday}")
    private Date birthday;
    private List<String> hobby;
    private Map<String, Object> assets;
    private Dog dog;
}

對應(yīng)配置文件:

person:
  name: qlh
  age: 22
  birthday: 2012/04/02
  hobby:
    - 打
    - 睡
    - 玩
    - 學(xué)
  assets:
    phone: iphone
    car: 福特野馬
  dog:
    name: 狗
    age: 1

?@PropertySource指定加載自定義的配置文件贷盲,默認只能加載properties格式淘这,但是可以指定factory屬性來加載YML格式的配置文件
同時加載多個配置

測試是否成功

編寫PropertiesController

@RestController
@RequestMapping("properties")
@Slf4j
public class PropertiesController {
    final
    Person person;

    public PropertiesController(Person person) {
        this.person = person;
    }
    @GetMapping("getProperties")
    public Dict getProperties(){
        log.info(person.toString());
        return Dict.create().set("person", person);
    }
}

瀏覽器輸入:http://localhost:8081/springboot-properties/properties/getProperties驗證結(jié)果÷燎睿看到打印類信息钠怯,表示加載自定義YML格式的配置文件成功了。

"Madison龍少"

擴展功能

?SpringBoot還提供了@ImportResource注解加載外部配置文件曙聂,只不過@ImportResource通常用于加載Spring的xml配置文件

@ImportResource使用

?Spring Boot提出零xml的配置晦炊,因此Spring Boot默認情況下是不會主動識別項目中Spring的xml配置文件。為了能夠加載xml的配置文件筹陵,Spring Boot提供了@ImportResource注解刽锤,該注解可以加載Spring的xml配置文件镊尺,通常加于啟動類上朦佩。這里就不做贅述了,代碼參考下面。

//value:Spring的xml配置文件,支持多個庐氮。
@ImportResource(value = {"classpath:config/beans.xml"})
@SpringBootApplication
public class SpringbootPropertiesApplication {

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

}

Spring Boot多環(huán)境配置

多環(huán)境配置有什么好處呢语稠??弄砍?

?不同環(huán)境配置可以配置不同的參數(shù)

?便于部署仙畦,提高效率,減少出錯

yml多環(huán)境配置

application.yml 主配置文件

server:
  port: 8081
  servlet:
    context-path: /springboot-properties
#配置激活選項
spring:
  profiles:
    active: dev

application-dev.yml 開發(fā)配置文件

#指定屬于哪個環(huán)境
spring:
  profiles:
    - dev

application-prod.yml 生產(chǎn)配置文件

#指定屬于哪個環(huán)境
spring:
  profiles:
    - prop

application-test.yml 測試配置文件

#指定屬于哪個環(huán)境
spring:
  profiles:
    - test

properties多環(huán)境配置

(1)主配置文件:配置激活選項

spring.profiles.active=dev

(2)其他配置文件:指定屬于哪個環(huán)境(同yml音婶,只不過表現(xiàn)形式是key=value的,三個配置文件分別是:application-dev.properties,application-prod.properties,application-test.properties

yml多環(huán)境配置和properties多環(huán)境配置比較

Properties配置多環(huán)境:需要添加多個配置文件

yml配置多環(huán)境:可添加多個配置文件慨畸,可不添加,使用---分隔(案例如下面代碼)(不建議使用該方法衣式,這樣顯得配置文件臃腫寸士,強烈建議添加多個配置文件,也不費事碴卧。)

server:
  port: 8081
  servlet:
    context-path: /springboot-properties
spring:
  profiles:
    active: dev
---
spring:
  profiles:
    - test
---
spring:
  profiles:
    - prod
---
spring:
  profiles:
    - dev

一般使用的配置文件

?application.yml:是主配置文件弱卡,放一些項目通用的配置

?application-dev.yml:放平常開發(fā)的一些配置,比如說數(shù)據(jù)庫的連接地址住册、帳號密碼等

?application-prod.yml:放生產(chǎn)環(huán)境的一些配置婶博,比如說數(shù)據(jù)庫的連接地址、帳號密碼等

?application-test.yml:放測試環(huán)境需要用到的參數(shù)

"Madison龍少"

激活指定profile

  • 使用spring.profiles.active激活

?無論是使用上述多文檔塊的方式荧飞,還是新建application-test.yml文件凡人,都可以在配置文件中指定 spring.profiles.active=test 激活指定的profile。

  • 打成jar包運行時候使用命令行激活
java -jar XXXX-0.0.1-SNAPSHOT.jar --spring.profiles.active=test
  • 使用虛擬機參數(shù)激活
-Dspring.profiles.active=test
"Madison龍少"
  • 在java代碼中激活
@SpringBootApplication
public class SpringbootPropertiesApplication {
    public static void main(String[] args) {
        System.setProperty("spring.profiles.active", "test");
        SpringApplication.run(SpringbootPropertiesApplication.class, args);
    }

}
在這里插入圖片描述

結(jié)束語

感謝閱讀小生文章叹阔。祝大家早日富可敵國挠轴,實現(xiàn)財富自由。

寫文不易,一定要點贊条获、評論忠荞、收藏哦,感謝感謝感謝!!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子委煤,更是在濱河造成了極大的恐慌堂油,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碧绞,死亡現(xiàn)場離奇詭異府框,居然都是意外死亡,警方通過查閱死者的電腦和手機讥邻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門迫靖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兴使,你說我怎么就攤上這事系宜。” “怎么了发魄?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵盹牧,是天一觀的道長。 經(jīng)常有香客問我励幼,道長汰寓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任苹粟,我火速辦了婚禮有滑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嵌削。我一直安慰自己毛好,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布掷贾。 她就那樣靜靜地躺著睛榄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪想帅。 梳的紋絲不亂的頭發(fā)上场靴,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音港准,去河邊找鬼旨剥。 笑死,一個胖子當著我的面吹牛浅缸,可吹牛的內(nèi)容都是我干的轨帜。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼衩椒,長吁一口氣:“原來是場噩夢啊……” “哼蚌父!你這毒婦竟也來了哮兰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤苟弛,失蹤者是張志新(化名)和其女友劉穎喝滞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膏秫,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡右遭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缤削。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窘哈。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亭敢,靈堂內(nèi)的尸體忽然破棺而出滚婉,到底是詐尸還是另有隱情,我是刑警寧澤吨拗,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布满哪,位于F島的核電站婿斥,受9級特大地震影響劝篷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜民宿,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一娇妓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧活鹰,春花似錦哈恰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锌云,卻和暖如春荠医,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桑涎。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工彬向, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人攻冷。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓娃胆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親等曼。 傳聞我的和親對象是個殘疾皇子里烦,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

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