spring 5.0.x源碼學(xué)習(xí)系列八: 實(shí)例化bean之使用構(gòu)造方法創(chuàng)建bean阔加、自動(dòng)裝配與循環(huán)依賴

前言

一配乱、解析構(gòu)建bean過(guò)程

  • 構(gòu)建bean的過(guò)程太復(fù)雜,將根據(jù)我自己寫的流程圖來(lái)一一講解

1.1 流程圖

在這里插入圖片描述

1.2 流程圖解析

1.2.1 創(chuàng)建非抽象于毙、單例敦冬、非懶加載的bean

整個(gè)正常流程是遍歷bean工廠存放beanName的list, 并根據(jù)beanName拿到對(duì)應(yīng)的beanDefinition,只過(guò)濾掉非抽象唯沮、單例脖旱、非懶加載的beand進(jìn)行創(chuàng)建

1.2.2 判斷當(dāng)前創(chuàng)建bean的類型并作相應(yīng)處理

因?yàn)閟pring存在兩種bean, 普通beanFactoryBean,spring在區(qū)分這兩種bean的做法是beanName和beanType來(lái)雙重校驗(yàn)的介蛉。假設(shè)獲取的bean為FactoryBean萌庆,那么會(huì)在getBean之前在beanName前添加一個(gè)&符號(hào)

    if (isFactoryBean(beanName)) {
        // org.springframework.beans.factory.BeanFactory#FACTORY_BEAN_PREFIX
        // String FACTORY_BEAN_PREFIX = "&";
        Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
        // 后面的邏輯省略
    }

1.2.3 getBean <=> doGetBean獲取bean的通用方法

  • 此方法是spring根據(jù)beanName獲取bean的通用方法。在此方法中有兩個(gè)地方需要注意:
  1. 內(nèi)部會(huì)對(duì)傳入的beanName做處理(將傳入的beanName前面的&符號(hào)去掉并存入內(nèi)部自己維護(hù)的一個(gè)變量中)币旧, 此時(shí)關(guān)于當(dāng)前bean的名稱會(huì)有兩個(gè)變量存儲(chǔ)践险,分別是name(方法傳入的bean名稱), beanName(處理過(guò)bean名稱)
  2. 不管是從bean工廠的單例池中獲取還是新建的bean, 最終都要走getObjectForBeanInstance方法來(lái)返回bean。這樣做主要是為了處理獲取的bean類型為FactoryBean的情況吹菱。
    具體規(guī)則可參考此鏈接:https://github.com/AvengerEug/spring/tree/develop/resourcecode-study#%E5%8D%81%E4%B8%80-%E8%8E%B7%E5%8F%96factorybean%E5%AE%9E%E4%BE%8B%E4%B8%8E%E5%AE%83%E7%BB%B4%E6%8A%A4%E7%9A%84bean%E5%AE%9E%E4%BE%8B%E8%A7%84%E5%88%99

1.2.4 第一次getSingleon

  • 此方法很重要
  1. 正常邏輯(循環(huán)bean工廠挨個(gè)創(chuàng)建bean)進(jìn)來(lái), 這里獲取的值肯定為null
  2. 在populateBean自動(dòng)裝配需要?jiǎng)?chuàng)建依賴bean時(shí), 這里獲取的可能為null也可能不為null. 只有在循環(huán)依賴和spring單例池存在bean的情況下, 獲取的才不為null, 因?yàn)榇朔椒〞?huì)首先從單例池中獲取bean, 若不存在再根據(jù)這個(gè)bean是否正在被創(chuàng)建從而到"特殊"(根據(jù)beanName到singletonFactories拿ObjectFactory, 并根據(jù)ObjectFactory獲取bean巍虫。
    public Object getSingleton(String beanName)
    

1.2.5 第二次調(diào)用getSingleton

  • 此方法只有在創(chuàng)建新的bean時(shí)才會(huì)用到,傳入的ObjectFactory是當(dāng)前類的createBean方法
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)
    

1.2.6 getSingleton內(nèi)部的beforeSingletonCreation方法

  • 標(biāo)記bean正在被創(chuàng)建:此動(dòng)作很重要, 主要是將beanName存放至DefaultSingletonBeanRegistry類的singletonsCurrentlyInCreation數(shù)據(jù)結(jié)構(gòu)(Set<String>), 后續(xù)會(huì)根據(jù)這個(gè)依據(jù)來(lái)解決循環(huán)依賴的情況, 即上述1.2.4 第一次getSingleon中所說(shuō)的獲取不為null的情況
    protected void beforeSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }
    

1.2.7 調(diào)用傳入的createBean方法<=>singletonFactory.getObject()

  • 內(nèi)部會(huì)調(diào)用至doCreateBean方法

1.2.8 doCreateBean方法

  • 內(nèi)部會(huì)創(chuàng)建出來(lái)bean, 創(chuàng)建完后還會(huì)在此方法中進(jìn)行自動(dòng)裝配populateBean

1.2.9 createBeanInstance方法

  • 此方法為真正創(chuàng)建bean的流程鳍刷,內(nèi)部主要做了如下事情
  1. 確定當(dāng)前bean是否通過(guò)構(gòu)造方法自動(dòng)裝配, 源碼和條件如下:

    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
       if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
               mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
           return autowireConstructor(beanName, mbd, ctors, args);
       }
    
    1. ctors != null  => ctors中存的是構(gòu)造方法中添加@Autowired注解的情形
    2. mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR  => 此條件為使用后置處理器手動(dòng)修改beanDefinition的自動(dòng)裝配的值, 默認(rèn)為no
    3. mbd.hasConstructorArgumentValues()
        => 使用后置處理器手動(dòng)添加beanDefinition中存放構(gòu)造方法值的情形,
         eg: mybatis中的definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName());
    4. !ObjectUtils.isEmpty(args)
    
    上述條件只要滿足一個(gè)就走構(gòu)造方法自動(dòng)裝配的邏輯
        ```
    
  2. 若使用構(gòu)造方法自動(dòng)裝配的結(jié)論不成立則走默認(rèn)構(gòu)造方法創(chuàng)建bean流程

  3. 不管是默認(rèn)構(gòu)造方法創(chuàng)建bean還是通過(guò)構(gòu)造方法自動(dòng)裝配bean占遥,所有bean的創(chuàng)建使用的都是CglibSubclassingInstantiationStrategy策略

1.2.10 確認(rèn)當(dāng)前bean是否符合循環(huán)依賴的情況 <=> addSingletonFactory方法

  • 滿足循環(huán)依賴的三個(gè)條件: 單例、allowCircularReferences為true输瓜、當(dāng)前的bean正在創(chuàng)建中
        protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(singletonFactory, "Singleton factory must not be null");
            synchronized (this.singletonObjects) {
                if (!this.singletonObjects.containsKey(beanName)) {
                    // 存放bean對(duì)應(yīng)的ObjectFactory, 在bean的循環(huán)依賴中會(huì)用上
                    this.singletonFactories.put(beanName, singletonFactory);
                    this.earlySingletonObjects.remove(beanName);
                    // 存放已經(jīng)被注冊(cè)過(guò)的bean
                    this.registeredSingletons.add(beanName);
                }
            }
        }
    
  • 使用構(gòu)造方法創(chuàng)建bean后, 會(huì)做三個(gè)操作:
  1. this.singletonFactories.put(beanName, singletonFactory);
    => 在getBean方法的第一次getSingleton中會(huì)用到瓦胎,其實(shí)這個(gè)singletonFactory的形參中已經(jīng)在創(chuàng)建bean的過(guò)程中傳入了,并且內(nèi)部的邏輯是執(zhí)行SmartInstantiationAwareBeanPostProcessor后置處理器的getEarlyBeanReference方法尤揣,此方法可以返回一個(gè)bean)的地方去拿bean

  2. this.earlySingletonObjects.remove(beanName);

  3. this.registeredSingletons.add(beanName); => 此步驟只是為了記錄這個(gè)bean已經(jīng)被spring創(chuàng)建了或者正在被創(chuàng)建中

    所以創(chuàng)建一個(gè)bean后(還未依賴注入bean), 會(huì)在singletonFactories和registeredSingletons數(shù)據(jù)結(jié)構(gòu)中都存在相關(guān)記錄

1.2.11 自動(dòng)裝配 <=> populateBean方法

  • 此方法中主要是AutowiredAnnotationBeanPostProcessor后置處理器來(lái)實(shí)現(xiàn)自動(dòng)裝配搔啊,若bean需要自動(dòng)裝配,則還需要先實(shí)例化依賴的bean芹缔,最終又會(huì)走到上述getBean邏輯

1.2.12 bean創(chuàng)建完畢, 開始執(zhí)行bean的一些后置處理器

  1. 調(diào)用bean的BeanPostProcessor后置處理器postProcessBeforeInitialization方法
  2. 若bean實(shí)現(xiàn)了InitializingBean接口, 則調(diào)用接口中的方法afterPropertiesSet
  3. 調(diào)用bean的BeanPostProcessor后置處理器de postProcessAfterInitialization方法

1.2.13 清除bean正在創(chuàng)建的標(biāo)識(shí)并添加至bean工廠

  • afterSingletonCreation
    // this.singletonsCurrentlyInCreation.remove(beanName) => 移除當(dāng)前bean name
    protected void afterSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
            throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
        }
    }
  • addSingleton
    protected void addSingleton(String beanName, Object singletonObject) {
        synchronized (this.singletonObjects) {
            // bean工廠單例池
            this.singletonObjects.put(beanName, singletonObject);
            // 執(zhí)行到這表示當(dāng)前bean已經(jīng)創(chuàng)建完成, 則移除循環(huán)依賴的bean的情況, 
            // 若下次還有bean依賴它, 直接從bean工廠的單例池獲取即可
            this.singletonFactories.remove(beanName);

            // 當(dāng)前bean被創(chuàng)建完畢坯癣,則清除它
            this.earlySingletonObjects.remove(beanName);

            // 再次將bean添加至該集合中, 該集合是一個(gè)set, 不會(huì)重復(fù), 這里重復(fù)添加的原因可能是并發(fā)情況
            this.registeredSingletons.add(beanName);
        }
    }

二瓶盛、一個(gè)案例搞清楚循環(huán)依賴

2.1 案例背景

  • 有兩個(gè)類: A和B最欠,它們互相依賴(A中要自動(dòng)裝配B屬性,B中要自動(dòng)裝配A屬性), 假設(shè)先創(chuàng)建A

2.2 流程

  1. 創(chuàng)建Bean a <=> getBean("a")
    第一次調(diào)用getSingleton方法, 單例池中無(wú)bean a 惩猫,也沒(méi)標(biāo)識(shí)正在被創(chuàng)建, 所以走第二個(gè)getSingleton方法芝硬。此時(shí)a被標(biāo)注正在被創(chuàng)建走使用構(gòu)造方法創(chuàng)建bean的邏輯
  2. 在創(chuàng)建完a后開始記錄bean a的一些狀態(tài)(將bean name添加至registeredSingletons以及將bean對(duì)應(yīng)的ObjectFactory添加至singletonFactories。即上述的addSingletonFactory方法的操作)和填充屬性, 發(fā)現(xiàn)它依賴于B, 此時(shí)要去getBean(b)
  3. 然后進(jìn)入創(chuàng)建bean b流程 <=> getBean("b")
  4. 此時(shí)會(huì)進(jìn)入第一個(gè)getSingleton方法, 此時(shí)spring單例池中無(wú)b并且b也還未被標(biāo)注為被創(chuàng)建(因?yàn)樗窃趃etSingleton方法后面標(biāo)注的)狀態(tài)所以進(jìn)入創(chuàng)建createBean方法
  5. 同理, 在創(chuàng)建完b后也會(huì)記錄bean b的一些狀態(tài)(將bean name添加至registeredSingletons以及將bean對(duì)應(yīng)的ObjectFactory添加至singletonFactories轧房。即上述的addSingletonFactory方法的操作)
  6. 創(chuàng)建完b后開始填充屬性, 發(fā)現(xiàn)它又依賴于A, 此時(shí)要去getBean("a")
  7. 此時(shí)進(jìn)入第一個(gè)getSingleton方法, 發(fā)現(xiàn)單例池中無(wú)a(雖然a在上述過(guò)程中被創(chuàng)建了, 但是它還未放入單例池中)但是它是處于被創(chuàng)建的狀態(tài), 所以從singletonFactories中根據(jù)beanName拿ObjectFactory, 最終從ObjectFactory拿到Bean a, 并將singletonFactories中beanName對(duì)應(yīng)的objectFactory remove掉,以及將拿到的bean a放入到earlySingletonObjects中
  8. 最終拿到了bean a, 此時(shí)將bean a注入到bean b中的a屬性中, 完成bean b的創(chuàng)建(此時(shí)會(huì)將它正在創(chuàng)建的標(biāo)識(shí)移除并它放入單例池中去), 并調(diào)用BeanPostProcessor后置處理器以及InitializingBean接口的afterPropertiesSet方法, 至此bean b的創(chuàng)建結(jié)束了 返回bean b拌阴。
  9. 因?yàn)樯鲜鰟?chuàng)建bean b的過(guò)程是a要自動(dòng)裝配b而執(zhí)行的, 為的就是獲取bean b。現(xiàn)在已經(jīng)拿到bean b了, 所以將bean a中的b屬性給注入進(jìn)去, 最終完成bean a的創(chuàng)建, 將a也添加到spring單例池中并調(diào)用BeanPostProcessor后置處理器以及InitializingBean接口的afterPropertiesSet方法
  10. bean a創(chuàng)建完成奶镶,循環(huán)依賴步驟完成
  • 涉及到的幾個(gè)數(shù)據(jù)結(jié)構(gòu):
    1. registeredSingletons: 表示該bean已經(jīng)通過(guò)構(gòu)造方法創(chuàng)建出來(lái)了
    2. singletonFactories: 存放bean對(duì)應(yīng)的objectFactory方法, 循環(huán)依賴時(shí)需要根據(jù)它來(lái)拿bean
    3. earlySingletonObjects: 與singletonFactories的操作是互斥的, 里面存放的是singletonFactories中beanName對(duì)應(yīng)的objectFactory創(chuàng)建出來(lái)的bean,若一個(gè)beanName在該集合中存在, 那么該bean對(duì)應(yīng)的ObjectFactory就會(huì)在singletonFactories中被remove掉
    4. singletonsCurrentlyInCreation: 表示當(dāng)前bean正在被創(chuàng)建, 在getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法中進(jìn)行操作, 添加迟赃、移除正在創(chuàng)建的標(biāo)識(shí)都是在此方法中完成

三陪拘、spring bean實(shí)例化過(guò)程中涉及到的后置處理器和執(zhí)行順序

執(zhí)行順序 執(zhí)行位置 執(zhí)行到的后置處理器 執(zhí)行的方法 作用
1 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.doCreateBean
=> resolveBeforeInstantiation方法
InstantiationAwareBeanPostProcessor 1. postProcessBeforeInstantiation
2.postProcessAfterInitialization
1. postProcessBeforeInstantiation作用:
若后置處理器中返回了一個(gè)對(duì)象, 則不會(huì)走spring的創(chuàng)建bean的流程
2.若postProcessBeforeInstantiation方法返回的bean不為null則執(zhí)行postProcessAfterInitialization方法,該方法執(zhí)行了BeanPostProcessor后置處理器, 自動(dòng)裝配的后置處理器就間接實(shí)現(xiàn)了BeanPostProcessor, 若BeanPostProcessor不被執(zhí)行, 那么自動(dòng)裝配的功能也將缺失
3. 若bean中實(shí)現(xiàn)了aware接口纤壁,那么將按照aware的類型誒個(gè)執(zhí)行對(duì)應(yīng)的方法左刽,其中就包括獲取spring上下文的ApplicationContextAware
2 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.createBeanInstance
=> determineConstructorsFromBeanPostProcessors
SmartInstantiationAwareBeanPostProcessor determineCandidateConstructors 掃描當(dāng)前bean攜帶@Autowired注解的構(gòu)造方法或者只有一個(gè)帶參的構(gòu)造方法或者等等其他的情況。(具體參考AutowiredAnnotationBeanPostProcessor類的determineCandidateConstructors方法)
3 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.doCreateBean
=> applyMergedBeanDefinitionPostProcessors
MergedBeanDefinitionPostProcessor postProcessMergedBeanDefinition 將當(dāng)前類需要自動(dòng)裝配的屬性全部InjectionMetadata對(duì)象中(每個(gè)屬性對(duì)應(yīng)一個(gè)InjectionMetadata對(duì)象)
4 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.doCreateBean
=> getEarlyBeanReference
SmartInstantiationAwareBeanPostProcessor getEarlyBeanReference 當(dāng)處理循環(huán)依賴時(shí)酌媒,會(huì)獲取到狀態(tài)為'正在創(chuàng)建'的bean的引用
5 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.populateBean
=> postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor postProcessAfterInstantiation 能夠控制當(dāng)前bean是否繼續(xù)完成依賴注入邏輯欠痴,若方法return false,則當(dāng)前bean的@Autowired注解功能的依賴注入結(jié)束
6 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.populateBean
=> postProcessPropertyValues
InstantiationAwareBeanPostProcessor postProcessPropertyValues 處理當(dāng)前bean自動(dòng)裝配的屬性
7 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.initializeBean => applyBeanPostProcessorsBeforeInitialization
BeanPostProcessor postProcessBeforeInitialization 當(dāng)bean被實(shí)例化并完成自動(dòng)裝配之后執(zhí)行
8 org.springframework.beans.factory.support.
AbstractAutowireCapableBeanFactory.initializeBean
=> applyBeanPostProcessorsAfterInitialization
BeanPostProcessor postProcessAfterInitialization 當(dāng)bean被實(shí)例化并完成自動(dòng)裝配之后執(zhí)行秒咨,比postProcessBeforeInitialization方法后執(zhí)行
  • 如上, 一共會(huì)執(zhí)行4個(gè)后置處理器InstantiationAwareBeanPostProcessor, SmartInstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, BeanPostProcessor, 共執(zhí)行了8次, 其中InstantiationAwareBeanPostProcessor類型的后置處理器調(diào)用次數(shù)最多, 8次調(diào)用中有5次跟它有關(guān), 因?yàn)樗^承了BeanPostProcessor, 并擴(kuò)展了三個(gè)方法postProcessBeforeInstantiation喇辽、 postProcessAfterInstantiation和postProcessPropertyValues

四、小結(jié)

  • 本篇博客還有很多細(xì)節(jié)未提及雨席,比如spring如何知道使用哪一個(gè)構(gòu)造方法(假設(shè)程序員提供了多個(gè)構(gòu)造器)創(chuàng)建bean菩咨、自動(dòng)裝配后置處理器AutowiredAnnotationBeanPostProcessor是如何知道哪些屬性需要裝配哪些不需要、在5個(gè)后置處理器的八個(gè)地方被調(diào)用的具體作用和景點(diǎn)案例也未完全總結(jié)等等舅世。只能等日后再完善了
  • I am a slow walker, but I never walk backwards.
  • github spring源碼學(xué)習(xí)地址: https://github.com/AvengerEug/spring/tree/develop/resourcecode-study
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末旦委,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子雏亚,更是在濱河造成了極大的恐慌缨硝,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罢低,死亡現(xiàn)場(chǎng)離奇詭異查辩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)网持,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門宜岛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人功舀,你說(shuō)我怎么就攤上這事萍倡。” “怎么了辟汰?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵列敲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我帖汞,道長(zhǎng)戴而,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任翩蘸,我火速辦了婚禮所意,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己扶踊,他們只是感情好泄鹏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秧耗,像睡著了一般命满。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绣版,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天胶台,我揣著相機(jī)與錄音,去河邊找鬼杂抽。 笑死诈唬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缩麸。 我是一名探鬼主播铸磅,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼杭朱!你這毒婦竟也來(lái)了阅仔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弧械,失蹤者是張志新(化名)和其女友劉穎八酒,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刃唐,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡羞迷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了画饥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片衔瓮。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抖甘,靈堂內(nèi)的尸體忽然破棺而出热鞍,到底是詐尸還是另有隱情,我是刑警寧澤衔彻,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布薇宠,位于F島的核電站,受9級(jí)特大地震影響米奸,放射性物質(zhì)發(fā)生泄漏昼接。R本人自食惡果不足惜爽篷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一悴晰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦铡溪、人聲如沸漂辐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)髓涯。三九已至,卻和暖如春哈扮,著一層夾襖步出監(jiān)牢的瞬間纬纪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工滑肉, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留包各,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓靶庙,卻偏偏與公主長(zhǎng)得像问畅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子六荒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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