Spring IOC 知識點(diǎn)匯總

laptop-iphone-coffee-notebook-thumb (1).jpg

@Configuration配置spring并啟動spring容器

@Configuration用于定義配置類链沼,標(biāo)注在類上材原,相當(dāng)于把該類作為spring的xml配置文件中的<beans>讥裤,作用是用于配置spring容器(應(yīng)用上下文)

實(shí)例說明:

配置類

@Configuration
public class MyConfig {
    public MyConfig() {
        System.out.println("TestConfig容器初始化E荏荨L桌EА悉默!");
    }
}

相當(dāng)于xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

測試類

public class TestConfig {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfig.class);
    }
}

運(yùn)行結(jié)果

TestConfig容器初始化!9赌隆3巍!

@Configuration&@Bean給容器中注冊組件

@Bean標(biāo)注在方法上鞭缭,相當(dāng)于xml配置配置中的<code></bean></code>

代碼實(shí)例說明:

注冊類

public class ConfigurationBean {
    public void start() {
        System.out.println("容器初始化開始F噬拧!A肜薄Vㄉ埂!");
    }
}

配置類

@Configuration
public class MyConfiguration {
    //可以指定bean 的名稱沦童,也可以指定注入容器之前加載的方法
    @Bean()
     public ConfigurationBean configurationBean(){
         return new ConfigurationBean();
     }

}

相當(dāng)于xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="configurationBean" class="zfcoding.bean.ConfigurationBean" ></bean> 
</beans>

測試方法

@Test
    public void ConfigurationTest(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class);
        ConfigurationBean configurationBean=(ConfigurationBean) applicationContext.getBean("configurationBean");
        System.out.println(configurationBean);
    }

運(yùn)行結(jié)果:

容器初始化開始B乇簟!M狄拧6胀!
zfcoding.bean.ConfigurationBean@77be656f

說明幾點(diǎn):

(1)氏豌、@Bean注解標(biāo)注在方法上喉酌,如果未通過@Bean指定bean的名稱,則默認(rèn)與標(biāo)注的方法名相同;

(2)泪电、@Bean注解標(biāo)注在方法上般妙,如果想通過@Bean指定bean的名稱,例如 @Bean("configurationBean1"),那么容器中實(shí)例化bean的名稱為configurationBean1相速;

@Bean 指定初始化和銷毀的方法及@Scope 碟渺,@Lazy

容器bean管理的生命周期:

我們可以自定義初始化和銷毀的方法,容器在bean進(jìn)行到當(dāng)前生命周期的時候來調(diào)用我們自定義的初始化和銷毀的方法突诬。

@Bean 中指定初始化和銷毀的方法苫拍。

@Bean(initMethod = "init",destroyMethod = "destory")

xml

<bean id="student" class="zfcoding.bean.Student"  init-method="init" destroy-method="destory"></bean>

@Scope

默認(rèn)情況下: singleton 單實(shí)例(默認(rèn)值),ioc容器啟動會調(diào)用方法創(chuàng)建對象放到ioc容器當(dāng)中旺隙。以后每次獲取直接獲取對象绒极。

prototype :多實(shí)例,ioc容器啟動并不會調(diào)用方法創(chuàng)建對象放到容器當(dāng)中催束。集峦,而是每次獲取的時候才會調(diào)用方法創(chuàng)建對象伏社,調(diào)用一次創(chuàng)建一次抠刺。

@Lazy 懶加載,

針對單實(shí)例bean,默認(rèn)在容器啟動的時候創(chuàng)建對象

懶加載:容器啟動不創(chuàng)鍵對象摘昌,第一次使用Bean創(chuàng)建對象速妖,并初始化。

實(shí)例說明:

public class Student {
    
    public Student() {
        System.out.println("Student容器加載開始4侠琛:比荨!稿饰!");
    }
    //對象創(chuàng)建完成锦秒,并賦值好崭孤,調(diào)用初始化方法......
    public void init() {
        System.out.println("Student.init()初始化開始.....");
    }
    //銷毀針對(單實(shí)例)歌逢,容器關(guān)閉的時候調(diào)用。
    //多實(shí)例(@Scope("prototype")):容器不會管理這個bean,容器也不回調(diào)用銷毀的方法预麸。
    public void destory() {
        System.out.println("Student.destory().........");
    }
}
@Configuration
public class MyConfigStudent {
    //@Lazy
    //@Scope("prototype")
    @Bean(value = "student",initMethod = "init",destroyMethod = "destory")
    public Student student(){
        return new Student();
    }
}

測試類一

public class MyConfigStudentTest {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfigStudent.class);
    }
}

運(yùn)行結(jié)果

Student容器加載開始B履贰I妗!捺宗!
Student.init()初始化開始.....

那么說明柱蟀,ioc容器啟動會調(diào)用方法創(chuàng)建對象放到ioc容器當(dāng)中。以后每次獲取直接獲取對象蚜厉。

如果我們使用@Lazy注解(單實(shí)例)长已,容器啟動不創(chuàng)鍵對象,測試結(jié)果沒有輸出信息。

測試類二,我們第一次使用Bean創(chuàng)建對象术瓮,并初始化

public class MyConfigStudentTest {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfigStudent.class);
        Student student = (Student)applicationContext.getBean("student");
        System.out.println(student);
        applicationContext.close();
    }
}

運(yùn)行結(jié)果

Student容器加載開始=汗!=锔早抠!
Student.init()初始化開始.....
zfcoding.bean.Student@7364985f
Student.destory().........

說明懶加載(@Lazy):當(dāng)容器啟動不創(chuàng)鍵對象,而是第一次使用Bean創(chuàng)建對象撬讽,并初始化蕊连。

InitializingBean 和DisposableBean

InitializingBean接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet方法游昼,凡是繼承該接口的類甘苍,在初始化bean的時候都會執(zhí)行該方法。

測試類

public class TestInitializingBean implements InitializingBean {
    public void afterPropertiesSet() throws Exception {
        System.out.println("TestInitializingBean.afterPropertiesSet()......");
    }

    public void init() {
        System.out.println("TestInitializingBean.init().......");
    }
}

配置類

@Configuration
public class MyInitializingBeanConfig {
    @Bean(value = "testInitializingBean",initMethod = "init")
    public TestInitializingBean testInitializingBean(){
        return new TestInitializingBean();
    }
}

測試類

public class TestnitializingBeanConfig {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyInitializingBeanConfig.class);
    }
}

運(yùn)行結(jié)果:

TestInitializingBean.afterPropertiesSet()......
TestInitializingBean.init().......

從結(jié)果可以看出烘豌,在Spring初始化bean的時候载庭,如果該bean實(shí)現(xiàn)了InitializingBean接口,并且同時在配置文件中指定了init-method廊佩,系統(tǒng)則是先調(diào)用afterPropertieSet()方法囚聚,然后再調(diào)用init-method中指定的方法。

那么這種方式在spring中是怎么實(shí)現(xiàn)的呢标锄,通過查看Spring加載bean的源碼類AbstractAutowiredCapableBeanFactory類中的invokeInitMethods(),如下:

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {
       判斷該bean是否實(shí)現(xiàn)了實(shí)現(xiàn)了InitializingBean接口顽铸,如果實(shí)現(xiàn)了InitializingBean接口,則只掉調(diào)用bean的afterPropertiesSet方法
        boolean isInitializingBean = (bean instanceof InitializingBean);
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (logger.isDebugEnabled()) {
                logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }
            if (System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                        @Override
                        public Object run() throws Exception {
                            ((InitializingBean) bean).afterPropertiesSet();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }
            else {
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }

        if (mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

總結(jié):

Spring為bean提供了兩種初始化bean的方式料皇,一種是實(shí)現(xiàn)InitializingBean接口谓松,重寫afterPropertiesSet方法,另一種四在配置文件中通過init-method指定践剂,但是如果同時指定的話是先調(diào)用InitializingBean實(shí)現(xiàn)的方法鬼譬。

@PostConstruct和@PreDestroy

可以使用JS250,@PostConstruct 標(biāo)注在方法上面,bean創(chuàng)建完成并且屬性賦值完成逊脯,來執(zhí)行初始化方法

@PreDestroy 优质,在容器銷毀bean之前通知我們進(jìn)行清理工作.

@ComponentScan&@Configuration給容器注冊組件

@Configuration+@ComponentScan 注入組件, 只是把標(biāo)注了注解為@Controller 男窟,@Service盆赤, @Repository, @Component 加入到Spring容器中.

xml 方式的配置

<context:component-scan base-package="zfcoding"></context:component-scan>

代碼實(shí)例說明:

需要注入的類

@Component
public class PersonComponent {
}
@Repository
public class PersonDao {
}
@Service
public class PersonService {
}
@Controller
public class PersonController {
}

配置類


@Configuration
//@ComponentScan(basePackages = "zfcoding",
////        includeFilters =@ComponentScan.Filter(type=FilterType.ANNOTATION,classes = Controller.class),useDefaultFilters=false )
@ComponentScan(basePackages = "zfcoding",
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class}))
public class MyCompoentScan {

}

測試的方法

 @Test
    public void ComponentSanTest(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyCompoentScan.class);
        String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String definitionName:definitionNames){
            System.out.println(definitionName);
        }
    }

運(yùn)行結(jié)果

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myCompoentScan
personComponent
personDao

說明:

excludeFilters 排除不需要加載的組件

includeFilters 只包含需要加載的組件歉眷,使用的時候需要把 useDefaultFilters=false牺六,才能生效

@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class}),指定的過濾規(guī)則,排除注解標(biāo)注是@Controller和@Service 類汗捡。

@Conditional-設(shè)置組件作用域

按照一定的條件進(jìn)行判斷淑际,滿足條件給容器中注冊bean

自定義Conditional條件需要編寫一個類畏纲,這個類需要實(shí)現(xiàn)Condition接口,我們直接使用就@Conditional({WindowsEnvironment.class})

@Conditional既可以定義在方法上春缕,也可以定義在類上盗胀,代碼實(shí)現(xiàn)自定義條件需要實(shí)現(xiàn)Condition接口

條件類

public class WindowsEnvironment implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        String property = environment.getProperty("os.name");
        BeanDefinitionRegistry registry = context.getRegistry();
        if(property.contains("Windows 10")){
           return true;
        }
        return false;
    }
}
public class LiunxEnvironment implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        if (environment.containsProperty("Liunx")){
            return true;
        }
        return false;
    }
}

配置類

@Configuration
public class MyCondition {

    @Conditional({WindowsEnvironment.class})
    @Bean
    public ConfigurationBean configurationBean(){
        return new ConfigurationBean("張三");
    }
    @@Conditional({LiunxEnvironment.class})
    @Bean
    public ConfigurationBean configurationBean1(){
        return new ConfigurationBean("李四");
    }
}

測試方法

public class CoditionTest {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyCondition.class);
        String[] beanNamesForType = applicationContext.getBeanNamesForType(ConfigurationBean.class);
        for (String s:beanNamesForType){
            System.out.println(s);
        }
    }
}

運(yùn)行結(jié)果

configurationBean

@Import 給容器快速導(dǎo)入一個組件

1、@Import(要導(dǎo)入的組件)锄贼,容器就會自動注冊這個組件票灰,id默認(rèn)是全類名。

2宅荤、ImportSelector 屑迂, 自定義邏輯返回要導(dǎo)入的組件 編寫的類學(xué)要實(shí)現(xiàn) ImportSelector 接口,返回需要導(dǎo)入的主鍵的全類名數(shù)組冯键。

3惹盼、ImportBeanDefinitionRegistrar,自定義邏輯需要編寫類實(shí)現(xiàn)ImportBeanDefinitionRegistrar接口,手動注冊bean到容器當(dāng)中惫确。

代碼實(shí)例

public class Red {
}
public class Blue {
}
//
@Import({Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public class MyImport {
   
}
public class MyImportSelector implements ImportSelector {

    //AnnotationMetadata :當(dāng)前標(biāo)注@Import 注解類的所有注解信息
    //返回類的全類名
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {

        return new String[]{"zfcoding.bean.Blue"};
    }
}

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
     //importingClassMetadata:當(dāng)前類的注解信息
    //BeanDefinitionRegistry  BeanDefinition注冊類手报,把所有需要添加到容器中的bean,BeanDefinitionRegistry.registerBeanDefinition手工注冊

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean red = registry.containsBeanDefinition("zfcoding.bean.Red");
        if (red){
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Blue.class);
            registry.registerBeanDefinition("blue",rootBeanDefinition);
        }

    }
}

測試類

public class ImportTest {
    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyImport.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String s:beanDefinitionNames){
            System.out.println(s);
        }
    }
}

運(yùn)行結(jié)果

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactorymyImport
zfcoding.bean.Red
zfcoding.bean.Blue
blue

總結(jié):

給容器中導(dǎo)入組件:

? 1、@Configuration&@Bean給容器中注冊組件

? 2改化、@ComponentScan&@Configuration(@Controller 掩蛤,@Service, @Repository所袁, @Component)

? 3盏档、@Import 快速的給容器中導(dǎo)入一個組件

@Value賦值 和@PropertySource 加載外部配置文件

@Value

? 1、基本數(shù)值

? 2燥爷、SPEL #{}

? 3、 可以寫${},去配置文件中的值(運(yùn)行環(huán)境中的值)

使用@PropertySource去取外部配置文件中的值保存到運(yùn)行的環(huán)境當(dāng)中懦窘。加載完尾部的配置文件之后前翎,使用${}取出配置文件中的值.

代碼實(shí)例:

代碼省略setter(),getter(),toString()方法。

public class Person {
    @Value("張三")
    private String name;
    @Value("#{20-1}")
    private Integer age;
    @Value("${person.sex}")
    private String sex;
}

//<context:property-placeholder location="person.properties"></context:property-placeholder>
@PropertySource("classpath:person.properties")
@Configuration
public class MyConfigValue {
      @Bean
      public Person person(){
          return new Person();
      }
}

person.properties

person.sex=1

測試類

@Test
    public void test1(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfigValue.class);
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }

運(yùn)行結(jié)果

Person{name='張三', age=19, sex='1'}

@Autowired &@Qualifier&@Primary

自動裝配:

@Autowired自動注入畅涂,單個默認(rèn)優(yōu)先按照類型去容器中找到對應(yīng)的組件港华,默認(rèn)一定要將屬性賦值好,沒有找到就會報錯午衰,可以使用@Autowired (required=false),非必須的 ;

@Qualifier 立宜,指定需要裝配的組件id ;

@Primary 讓Spring 進(jìn)行自動裝配的時候, 首選裝配的組件(配置類中)臊岸,也可以使用@Qualifier指定需要裝配的bean的名字.

@Resource &@Inject

Spring還支持@Resource(JSR250)和@Inject (JSR330){java規(guī)范的注解}

@Resource 和@Autowired一樣實(shí)現(xiàn)自動裝配的功能橙数,默認(rèn)按照組件的名稱進(jìn)行裝配。

@Inject需要導(dǎo)入javax.inject的包帅戒,和@Autowired功能一樣灯帮,沒有required=false的功能。

@Profile 環(huán)境搭建

Spring 為我們提供可以根據(jù)當(dāng)前環(huán)境,動態(tài)的激活和切換一系列組件的功能

下面我們來使用數(shù)據(jù)源說明這個問題:

@Profile指定哪個環(huán)境下才能被注冊到容器當(dāng)中钟哥,加了@Profile迎献,只有這個環(huán)境激活的時候才能注冊到spring容器當(dāng)中,默認(rèn)是defalut

代碼實(shí)例:

@PropertySource("classpath:db.properties")
@Configuration
public class MyConfigProfile  implements EmbeddedValueResolverAware {
    @Value("${db.username}")
    private String username;
    @Value("${db.password=}")
    private String password;

    private StringValueResolver stringValueResolver;

    private String driveClass;

    @Profile("default")
    @Bean("testDataSource")
    public DataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
        dataSource.setUser(username);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/springboot?serverTimezone=UTC&useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8");
        dataSource.setDriverClass(driveClass);
        return dataSource;
    }
    @Profile("dev")
    @Bean("devDataSource")
    public DataSource devDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource=new ComboPooledDataSource();
        dataSource.setUser(username);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/springboot?serverTimezone=UTC&useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8");
        dataSource.setDriverClass(driveClass);
        return dataSource;
    }

    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.stringValueResolver=resolver;
        driveClass = stringValueResolver.resolveStringValue("db.driverClass");
    }
}

db.properties

db.username=root
db.password=root
db.driverClass=com.mysql.jdbc.Driver

測試代碼:

public class DataSourceProfileTest {
    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MyConfigProfile.class);
        String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);
        for (String s:beanNamesForType){
            System.out.println(s);
        }
    }
    
    /* 使用無參構(gòu)造器
     * 設(shè)置激活的環(huán)境
     * 注冊主配置類
     * 啟動刷新容器
     */
    @Test
    public void test1(){
        //使用無參構(gòu)造器 
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext();
        //設(shè)置激活的環(huán)境
        applicationContext.getEnvironment().setActiveProfiles("dev");
        //注冊主配置類
        applicationContext.register(MyConfigProfile.class);
        //啟動刷新容器
        applicationContext.refresh();
        String[] beanNamesForType = applicationContext.getBeanNamesForType(DataSource.class);
        for (String s:beanNamesForType){
            System.out.println(s);
        }
    }
}

測試案例運(yùn)行結(jié)果

testDataSource

devDataSource

小結(jié):

@Profile還可以標(biāo)記在類上腻贰,表示只有指定環(huán)境的時候吁恍,整個配置文件里面的配置才能開始生效。沒有標(biāo)注環(huán)境表示的bean播演,在任何環(huán)境下都是加載的(前提是配置類是生效的),還可以通過命令行參數(shù):<code>-Dspring.profiles.active=test</code>激活對應(yīng)的環(huán)境宾巍。

我是阿福,公眾號「阿福聊編程」作者顶霞,對后端技術(shù)保持學(xué)習(xí)愛好者,我會經(jīng)常更新JAVA技術(shù)文章选浑,在進(jìn)階的路上,共勉古徒!

歡迎大家關(guān)注我的公眾號,后臺回復(fù)666隧膘,領(lǐng)取福利,你懂的疹吃。

[圖片上傳失敗...(image-f04d6e-1592872109509)]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市萨驶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腔呜,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件核畴,死亡現(xiàn)場離奇詭異膝但,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)膛檀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門锰镀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娘侍,“玉大人,你說我怎么就攤上這事泳炉『斗ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵花鹅,是天一觀的道長氧腰。 經(jīng)常有香客問我,道長刨肃,這世上最難降的妖魔是什么古拴? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮真友,結(jié)果婚禮上黄痪,老公的妹妹穿的比我還像新娘。我一直安慰自己盔然,他們只是感情好桅打,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著愈案,像睡著了一般挺尾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上站绪,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天遭铺,我揣著相機(jī)與錄音,去河邊找鬼恢准。 笑死魂挂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的顷歌。 我是一名探鬼主播锰蓬,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眯漩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起麻顶,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤赦抖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后队萤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矫钓,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年既绩,在試婚紗的時候發(fā)現(xiàn)自己被綠了饲握。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片救欧。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡笆怠,死狀恐怖誊爹,靈堂內(nèi)的尸體忽然破棺而出替废,到底是詐尸還是另有隱情,我是刑警寧澤诈火,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布冷守,位于F島的核電站拍摇,受9級特大地震影響馆截,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜混卵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一幕随、第九天 我趴在偏房一處隱蔽的房頂上張望赘淮。 院中可真熱鬧,春花似錦走诞、人聲如沸低剔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涧黄,卻和暖如春赋荆,著一層夾襖步出監(jiān)牢的瞬間窄潭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工月帝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嚷辅,地道東北人距误。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓准潭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子殉簸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348