Spring源碼----Spring的Bean生命周期流程圖及代碼解釋

?在網(wǎng)上已經(jīng)有跟多Bean的生命周期的博客橄杨,但是很多都是基于比較老的版本了竣况,最近吧整個(gè)流程化成了一個(gè)流程圖摹恨。待會(huì)兒使用流程圖,說(shuō)明以及代碼的形式來(lái)說(shuō)明整個(gè)聲明周期的流程娶视。注意因?yàn)榇a比較多晒哄,這里的流程圖只畫(huà)出了大概的流程,具體的可以深入代碼

1.獲取Bean

第一階段獲取Bean

?這里的流程圖的入口在AbstractBeanFactory類(lèi)的doGetBean方法肪获,這里可以配合前面的getBean方法分析文章進(jìn)行閱讀寝凌。主要流程就是

  1. 先處理Bean 的名稱(chēng),因?yàn)槿绻浴?amp;”開(kāi)頭的Bean名稱(chēng)表示獲取的是對(duì)應(yīng)的FactoryBean對(duì)象孝赫;
  2. 從緩存中獲取單例Bean较木,有則進(jìn)一步判斷這個(gè)Bean是不是在創(chuàng)建中,如果是的就等待創(chuàng)建完畢寒锚,否則直接返回這個(gè)Bean對(duì)象
  3. 如果不存在單例Bean緩存劫映,則先進(jìn)行循環(huán)依賴(lài)的解析
  4. 解析完畢之后先獲取父類(lèi)BeanFactory,獲取到了則調(diào)用父類(lèi)的getBean方法刹前,不存在則先合并然后創(chuàng)建Bean

2.創(chuàng)建Bean

2.1 創(chuàng)建Bean之前

在真正創(chuàng)建Bean之前邏輯

?這個(gè)流程圖對(duì)應(yīng)的代碼在AbstractAutowireCapableBeanFactory類(lèi)的createBean方法中。

  1. 這里會(huì)先獲取RootBeanDefinition對(duì)象中的Class對(duì)象并確保已經(jīng)關(guān)聯(lián)了要?jiǎng)?chuàng)建的Bean的Class雌桑。
  2. 這里會(huì)檢查3個(gè)條件
    (1)Bean的屬性中的beforeInstantiationResolved字段是否為true喇喉,默認(rèn)是false。
    (2)Bean是原生的Bean
    (3)Bean的hasInstantiationAwareBeanPostProcessors屬性為true校坑,這個(gè)屬性在Spring準(zhǔn)備刷新容器錢(qián)轉(zhuǎn)杯BeanPostProcessors的時(shí)候會(huì)設(shè)置拣技,如果當(dāng)前Bean實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor則這個(gè)就會(huì)是true。
    當(dāng)三個(gè)條件都存在的時(shí)候耍目,就會(huì)調(diào)用實(shí)現(xiàn)的InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法膏斤,然后獲取返回的Bean,如果返回的Bean不是null還會(huì)調(diào)用實(shí)現(xiàn)的BeanPostProcessor接口的postProcessAfterInitialization方法邪驮,這里用代碼說(shuō)明
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
              //條件1
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
          //條件2跟條件3
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
 //調(diào)用實(shí)現(xiàn)的postProcessBeforeInstantiation方法
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
//調(diào)用實(shí)現(xiàn)的postProcessAfterInitialization方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
                  //不滿(mǎn)足2或者3的時(shí)候就會(huì)設(shè)置為false
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

  1. 如果上面3個(gè)條件其中一個(gè)不滿(mǎn)足就不會(huì)調(diào)用實(shí)現(xiàn)的方法莫辨。默認(rèn)這里都不會(huì)調(diào)用的這些BeanPostProcessors的實(shí)現(xiàn)方法。然后繼續(xù)執(zhí)行后面的doCreateBean方法。
2.1 真正的創(chuàng)建Bean沮榜,doCreateBean

doCreateBean方法邏輯

這個(gè)代碼的實(shí)現(xiàn)還是在AbstractAutowireCapableBeanFactory方法中盘榨。流程是

  1. 先檢查instanceWrapper變量是不是null,這里一般是null蟆融,除非當(dāng)前正在創(chuàng)建的Bean在factoryBeanInstanceCache中存在這個(gè)是保存還沒(méi)創(chuàng)建完成的FactoryBean的集合草巡。
  2. 調(diào)用createBeanInstance方法實(shí)例化Bean,這個(gè)方法在后面會(huì)講解
  3. 如果當(dāng)前RootBeanDefinition對(duì)象還沒(méi)有調(diào)用過(guò)實(shí)現(xiàn)了的MergedBeanDefinitionPostProcessor接口的方法型酥,則會(huì)進(jìn)行調(diào)用
  4. 當(dāng)滿(mǎn)足以下三點(diǎn)
    (1)是單例Bean
    (2)嘗試解析bean之間的循環(huán)引用
    (3)bean目前正在創(chuàng)建中
    則會(huì)進(jìn)一步檢查是否實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor接口如果實(shí)現(xiàn)了則調(diào)用是實(shí)現(xiàn)的getEarlyBeanReference方法
  5. 調(diào)用populateBean方法進(jìn)行屬性填充山憨,這里后面會(huì)講解
  6. 調(diào)用initializeBean方法對(duì)Bean進(jìn)行初始化,這里后面會(huì)講解
2.1.1 實(shí)例化Bean弥喉,createBeanInstance
實(shí)例化Bean

?這里的邏輯稍微有一點(diǎn)復(fù)雜萍歉,這個(gè)流程圖已經(jīng)是簡(jiǎn)化過(guò)后的了。簡(jiǎn)要根據(jù)代碼說(shuō)明一下流程

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //步驟1
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }
        //步驟2
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
        //步驟3
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }


        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        //步驟4.1
        if (resolved) {
                  
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                       
                return instantiateBean(beanName, mbd);
            }
        }

          //步驟4.2
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        //步驟5
        ctors = mbd.getPreferredConstructors();
        if (ctors != null) {
            return autowireConstructor(beanName, mbd, ctors, null);
        }

        
        return instantiateBean(beanName, mbd);
    }
  1. 先檢查Class是否已經(jīng)關(guān)聯(lián)了档桃,并且對(duì)應(yīng)的修飾符是否是public的
  2. 如果用戶(hù)定義了Bean實(shí)例化的函數(shù)枪孩,則調(diào)用并返回
  3. 如果當(dāng)前Bean實(shí)現(xiàn)了FactoryBean接口則調(diào)用對(duì)應(yīng)的FactoryBean接口的getObject方法
  4. 根據(jù)getBean時(shí)候是否傳入構(gòu)造參數(shù)進(jìn)行處理
    4.1 如果沒(méi)有傳入構(gòu)造參數(shù),則檢查是否存在已經(jīng)緩存的無(wú)參構(gòu)造器藻肄,有則使用構(gòu)造器直接創(chuàng)建蔑舞,沒(méi)有就會(huì)調(diào)用instantiateBean方法先獲取實(shí)例化的策略默認(rèn)是CglibSubclassingInstantiationStrategy,然后實(shí)例化Bean嘹屯。最后返回
    4.2 如果傳入了構(gòu)造參數(shù)攻询,則會(huì)先檢查是否實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor接口,如果實(shí)現(xiàn)了會(huì)調(diào)用determineCandidateConstructors獲取返回的候選構(gòu)造器州弟。
    4.3 檢查4個(gè)條件是否滿(mǎn)足一個(gè)
    (1)構(gòu)造器不為null钧栖,
    (2)從RootBeanDefinition中獲取到的關(guān)聯(lián)的注入方式是構(gòu)造器注入(沒(méi)有構(gòu)造參數(shù)就是setter注入,有則是構(gòu)造器注入)
    (3)含有構(gòu)造參數(shù)
    (4)getBean方法傳入構(gòu)造參數(shù)不是空
    滿(mǎn)足其中一個(gè)則會(huì)調(diào)用返回的候選構(gòu)造器實(shí)例化Bean并返回婆翔,如果都不滿(mǎn)足拯杠,則會(huì)根據(jù)構(gòu)造參數(shù)選則合適的有參構(gòu)造器然后實(shí)例化Bean并返回
  5. 如果上面都沒(méi)有合適的構(gòu)造器,則直接使用無(wú)參構(gòu)造器創(chuàng)建并返回Bean啃奴。
2.1.2 填充Bean潭陪,populateBean
填充Bean

這里還是根據(jù)代碼來(lái)說(shuō)一下流程

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // Skip property population phase for null instance.
                return;
            }
        }


        boolean continueWithPropertyPopulation = true;
        //步驟1
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }
//步驟2--------------------
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }

        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        PropertyDescriptor[] filteredPds = null;
//步驟3
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
//步驟4
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }
  1. 檢查當(dāng)前Bean是否實(shí)現(xiàn)了InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation方法則調(diào)用,并結(jié)束B(niǎo)ean的填充最蕾。
  2. 將按照類(lèi)型跟按照名稱(chēng)注入的Bean分開(kāi)依溯,如果注入的Bean還沒(méi)有實(shí)例化的這里會(huì)實(shí)例化,然后放到PropertyValues對(duì)象中瘟则。
  3. 如果實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor類(lèi)的postProcessProperties則調(diào)用這個(gè)方法并獲取返回值黎炉,如果返回值是null,則有可能是實(shí)現(xiàn)了過(guò)期的postProcessPropertyValues方法醋拧,這里需要進(jìn)一步調(diào)用postProcessPropertyValues方法
  4. 進(jìn)行參數(shù)填充
2.1.3 初始化Bean慷嗜,initializeBean
初始化Bean

同時(shí)這里根據(jù)代碼跟流程圖來(lái)說(shuō)明

  1. 如果Bean實(shí)現(xiàn)了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware則調(diào)用對(duì)應(yīng)實(shí)現(xiàn)的方法
  2. Bean不為null并且bean不是合成的淀弹,如果實(shí)現(xiàn)了BeanPostProcessorpostProcessBeforeInitialization則會(huì)調(diào)用實(shí)現(xiàn)的postProcessBeforeInitialization方法。在ApplicationContextAwareProcessor類(lèi)中實(shí)現(xiàn)了postProcessBeforeInitialization方法洪添。而這個(gè)類(lèi)會(huì)在Spring刷新容器準(zhǔn)備beanFactory的時(shí)候會(huì)加進(jìn)去垦页,這里就會(huì)被調(diào)用,而調(diào)用里面會(huì)檢查Bean是不是EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware的實(shí)現(xiàn)類(lèi)干奢。這里就會(huì)調(diào)用對(duì)應(yīng)的實(shí)現(xiàn)方法痊焊。代碼如下
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        .......
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        .......
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
            return bean;
        }

        AccessControlContext acc = null;

        if (System.getSecurityManager() != null) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }

        return bean;
    }
  1. 實(shí)例化Bean然后,檢查是否實(shí)現(xiàn)了InitializingBeanafterPropertiesSet方法忿峻,如果實(shí)現(xiàn)了就會(huì)調(diào)用
  2. Bean不為null并且bean不是合成的薄啥,如果實(shí)現(xiàn)了BeanPostProcessorpostProcessBeforeInitialization則會(huì)調(diào)用實(shí)現(xiàn)的postProcessAfterInitialization方法。

到此創(chuàng)建Bean 的流程就沒(méi)了逛尚,剩下的就是容器銷(xiāo)毀的時(shí)候的了

3.destory方法跟銷(xiāo)毀Bean

?Bean在創(chuàng)建完畢之后會(huì)檢查用戶(hù)是否指定了destroyMethodName以及是否實(shí)現(xiàn)了DestructionAwareBeanPostProcessor接口的requiresDestruction方法垄惧,如果指定了會(huì)記錄下來(lái)保存在DisposableBeanAdapter對(duì)象中并保存在bean的disposableBeans屬性中。代碼在AbstractBeanFactoryregisterDisposableBeanIfNecessary

    protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
          ......
                registerDisposableBean(beanName,
                        new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
            ......
    }
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
            List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
          .......
        String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
        if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
                !beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
            ......
            this.destroyMethod = destroyMethod;
        }
        this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
    }

?在銷(xiāo)毀Bean的時(shí)候最后都會(huì)調(diào)用AbstractAutowireCapableBeanFactorydestroyBean方法绰寞。

    public void destroyBean(Object existingBean) {
        new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
    }

這里是創(chuàng)建一個(gè)DisposableBeanAdapter對(duì)象到逊,這個(gè)對(duì)象實(shí)現(xiàn)了Runnable接口,在實(shí)現(xiàn)的run方法中會(huì)調(diào)用實(shí)現(xiàn)的DisposableBean接口的destroy方法滤钱。并且在創(chuàng)建DisposableBeanAdapter對(duì)象的時(shí)候會(huì)根據(jù)傳入的bean是否實(shí)現(xiàn)了DisposableBean接口來(lái)設(shè)置invokeDisposableBean變量觉壶,這個(gè)變量表實(shí)有沒(méi)有實(shí)現(xiàn)DisposableBean接口

    public DisposableBeanAdapter(Object bean, List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
        Assert.notNull(bean, "Disposable bean must not be null");
        this.bean = bean;
        this.beanName = bean.getClass().getName();
          //根據(jù)傳入的bean是否實(shí)現(xiàn)了`DisposableBean`接口來(lái)設(shè)置`invokeDisposableBean`變量
        this.invokeDisposableBean = (this.bean instanceof DisposableBean);
        this.nonPublicAccessAllowed = true;
        this.acc = acc;
        this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
    }

    public void destroy() {
        ......
  //根據(jù)invokeDisposableBean決定是否調(diào)用destroy方法
        if (this.invokeDisposableBean) {
            if (logger.isTraceEnabled()) {
                logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
            }
            try {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                        ((DisposableBean) this.bean).destroy();
                        return null;
                    }, this.acc);
                }
                else {
                    ((DisposableBean) this.bean).destroy();
                }
            }
            catch (Throwable ex) {
                String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
                if (logger.isDebugEnabled()) {
                    logger.warn(msg, ex);
                }
                else {
                    logger.warn(msg + ": " + ex);
                }
            }
        }
......
    }
4.總結(jié)。

最后來(lái)一個(gè)大的流程


實(shí)例化前的準(zhǔn)備階段

實(shí)例化前

實(shí)例化后

初始化前

初始化之后+銷(xiāo)毀

關(guān)于Spring的BeanFactoryPostProcessorBeanPostProcessor后面會(huì)介紹

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末件缸,一起剝皮案震驚了整個(gè)濱河市铜靶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌他炊,老刑警劉巖争剿,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異痊末,居然都是意外死亡蚕苇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)舌胶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捆蜀,“玉大人,你說(shuō)我怎么就攤上這事幔嫂。” “怎么了誊薄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵履恩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我呢蔫,道長(zhǎng)切心,這世上最難降的妖魔是什么飒筑? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮绽昏,結(jié)果婚禮上协屡,老公的妹妹穿的比我還像新娘。我一直安慰自己全谤,他們只是感情好肤晓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著认然,像睡著了一般补憾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卷员,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天盈匾,我揣著相機(jī)與錄音,去河邊找鬼毕骡。 笑死削饵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的未巫。 我是一名探鬼主播窿撬,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼橱赠!你這毒婦竟也來(lái)了尤仍?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狭姨,失蹤者是張志新(化名)和其女友劉穎宰啦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體饼拍,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赡模,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了师抄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漓柑。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖叨吮,靈堂內(nèi)的尸體忽然破棺而出辆布,到底是詐尸還是另有隱情,我是刑警寧澤茶鉴,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布锋玲,位于F島的核電站,受9級(jí)特大地震影響涵叮,放射性物質(zhì)發(fā)生泄漏惭蹂。R本人自食惡果不足惜伞插,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盾碗。 院中可真熱鬧媚污,春花似錦、人聲如沸廷雅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)榜轿。三九已至幽歼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谬盐,已是汗流浹背甸私。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留飞傀,地道東北人皇型。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像砸烦,于是被迫代替她去往敵國(guó)和親弃鸦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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