Spring AOP DefaultAdvisorAutoProxyCreator

Spring AOP源碼目錄

Spring AOP源碼01:Jdk動(dòng)態(tài)代理底層源碼
Spring AOP源碼02:ProxyFactory
Spring AOP源碼03:JdkDynamicAopProxy
Spring AOP源碼04:MethodInvocation 攔截器調(diào)用
Spring AOP源碼05:DefaultAdvisorAutoProxyCreator
Spring期末考?jí)狠S題:當(dāng)Spring AOP遇上循環(huán)依賴
git注釋源碼地址:https://github.com/chaitou/spring-framework-master.git

前言

前面已經(jīng)學(xué)習(xí)了ProxyFactory的源碼,學(xué)習(xí)了如何手動(dòng)硬編碼使用最基礎(chǔ)的Spring AOP,以及實(shí)現(xiàn)方式为黎。這一節(jié)要學(xué)習(xí)自動(dòng)代理DefaultAdvisorAutoProxyCreator源碼言缤。比起Spring AOP注解形式實(shí)現(xiàn)自動(dòng)代理竹握,我們之前學(xué)習(xí)的ProxyFactory還差以下2步:

  1. 代理時(shí)機(jī):在Spring Ioc創(chuàng)建Bean的過(guò)程中铣耘,尋找合適的時(shí)機(jī)進(jìn)行調(diào)用Spring AOP進(jìn)行代理
  2. 自動(dòng)代理:搜索所有bean中注解了@Aspect的類票堵,并且提取Advisor(切面)慎璧。當(dāng)一個(gè)正常的bean創(chuàng)建時(shí),從這些候選的Advisor(切面)通過(guò)Pointcut尋找與之匹配的Advice哄孤,最后生成攔截器耕驰,再調(diào)用Proxy.getProxy()獲取代理

一、代理時(shí)機(jī)

這一點(diǎn)應(yīng)該引起大家的注意录豺,因?yàn)楹芏鄷约安┛投紱](méi)有講明白朦肘,都是簡(jiǎn)單的一筆帶過(guò),但是筆者卻認(rèn)為如果連代理時(shí)機(jī)都弄不清楚双饥,還談什么自動(dòng)代理呢媒抠?

1. DefaultAdvisorAutoProxyCreator類圖

!](https://upload-images.jianshu.io/upload_images/8190955-bc261b8789f5ad01?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
之前的Spring Ioc源碼專題的生命周期中提到過(guò)這么一段話:

spring使用模板模式,在bean的創(chuàng)建過(guò)程中安插了許多錨點(diǎn)咏花,用戶尋找對(duì)應(yīng)的錨點(diǎn)趴生,通過(guò)重寫方法介入到bean的創(chuàng)建過(guò)程當(dāng)中。

想要介入Spring Ioc創(chuàng)建Bean的過(guò)程昏翰,最好的方式就是實(shí)現(xiàn)BeanPostProcessor苍匆,想必Spring AOP也正式通過(guò)這種方式介入Bean的創(chuàng)建,實(shí)現(xiàn)自動(dòng)代理的吧棚菊〗龋可以看到DefaultAdvisorAutoProxyCreator類圖最左邊的分支上就實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor,在DefaultAdvisorAutoProxyCreator的父類AbstractAutoProxyCreator中统求,我們找到了其實(shí)現(xiàn)的后置方法

AbstractAutoProxyCreator

  • postProcessBeforeInitialization 初始化前擴(kuò)展
  • postProcessAfterInitialization 初始化后擴(kuò)展
  • postProcessBeforeInstantiation 對(duì)象實(shí)例化前擴(kuò)展
  • postProcessAfterInstantiation 對(duì)象實(shí)例化后擴(kuò)展
  • postProcessPropertyValues 屬性依賴注入前擴(kuò)展

5個(gè)后置處理器检碗,只有2個(gè)有具體的實(shí)現(xiàn),分別是postProcessBeforeInstantiation實(shí)例化前和postProcessAfterInitialization初始化后

2. 源碼分析

我們從Spring Ioc創(chuàng)建開始跟中码邻,在創(chuàng)建bean

// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
         throws BeanCreationException {

      // 省略無(wú)關(guān)代碼...

      try {
         // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
         /**
          * 實(shí)例化前的后置處理器
          * 給BeanPostProcessors一個(gè)機(jī)會(huì)返回代理替換調(diào)真實(shí)的實(shí)例折剃,主要是來(lái)執(zhí)行實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
          *
          * ① 重點(diǎn):
          * AOP代理時(shí)機(jī) 1. 當(dāng)用戶自定義TargetSource將會(huì)在實(shí)例化前進(jìn)行代理,此時(shí)的TargetSource直接返回需要被代理的Bean像屋,也就是說(shuō)該被代理的Bean的實(shí)例化初始化操作均由自己負(fù)責(zé)怕犁。并進(jìn)行短路操作
          * 2. 用戶不自定義TargetSource時(shí)則返回空,在初始化后才進(jìn)行AOP代理
          */
         Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
         // ② 如果此時(shí)返回的bean不為空,直接短路奏甫,不再進(jìn)行bean的實(shí)例化戈轿、填充、初始化扶檐!
         if (bean != null) {
            return bean;
         }
      }
      catch (Throwable ex) {
         throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
               "BeanPostProcessor before instantiation of bean failed", ex);
      }

      try {
         // 核心邏輯
         Object beanInstance = doCreateBean(beanName, mbdToUse, args);
         if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
         }
         return beanInstance;
      }
      ...
   }

① 在bean實(shí)例化前的這個(gè)操作非常重要凶杖,之前我們?cè)赟pring Ioc時(shí)說(shuō)胁艰,這邊一般都返回空款筑,但是什么時(shí)候不返回空呢?帶著這個(gè)問(wèn)題繼續(xù)往下看源碼

② 當(dāng)不為空時(shí)腾么,直接就return了奈梳!也就是說(shuō)bean直接就不實(shí)例化、填充解虱、初始化了攘须!

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        // 確認(rèn)bean在初始化階段之前
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                // 確認(rèn)當(dāng)前beanName所要返回的最終類型
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    // 只有前置處理返回的bean不為null, 才進(jìn)行初始化后置處理(Aop的代理在初始化后置處理中進(jìn)行)
                    // 但是除非bean自定義了TargetSource,否則前置處理返回的bean為空
                    // 一般沒(méi)有自定義TargetSource情況下殴泰,是不會(huì)在實(shí)例化前調(diào)用該后置處理于宙,也不會(huì)導(dǎo)致后續(xù)短路操作!
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        // 實(shí)例化后置處理
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

前面我們提到5個(gè)后置處理器悍汛,只有2個(gè)有具體的實(shí)現(xiàn)捞魁,分別是postProcessBeforeInstantiation實(shí)例化前和postProcessAfterInitialization初始化后,跟上方代碼已經(jīng)完全對(duì)上了离咐。接下來(lái)我們就去AbstractAutoProxyCreator中看看這2個(gè)后置處理器到底做了什么工作

3. postProcessBeforeInstantiation

// AbstractAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
      // 省略無(wú)關(guān)代碼... 

      /**
       * 如果我們有自定義的TargetSource谱俭,在此處創(chuàng)建代理。
       * TargetSource將以自定義方式處理目標(biāo)實(shí)例宵蛀。
       */
      // 獲取自定義TargetSource
      TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
      if (targetSource != null) {
         if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
         }
         // 獲取攔截器
         Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
         // 生成代理昆著,跟之前說(shuō)過(guò)的Proxy.getProxy一樣的
         Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
         // 實(shí)在緩存
         this.proxyTypes.put(cacheKey, proxy.getClass());
         // 返回代理
         return proxy;
      }

      return null;
   }

只有targetSource != null才會(huì)返回bean,也就是說(shuō)只有自定義了targetSource术陶,從而導(dǎo)致后續(xù)短路操作凑懂。自定義targetSource的意思就是說(shuō)我們自己負(fù)責(zé)target的創(chuàng)建,不需要你Spring Ioc插手梧宫。那么targetSource到底有什么用呢征候?例如CommonsPoolTargetSource:可以池化TargetSource,每次執(zhí)行時(shí)從池中取代理對(duì)象祟敛,執(zhí)行完方法再返回池中疤坝,這里不扯遠(yuǎn)

4. postProcessAfterInitialization

    // AbstractAutoProxyCreator.java
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            // 緩存key,一般為beanClassName_beanName
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // bean如果有需要將會(huì)被AOP代理
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

5. 代理時(shí)機(jī)總結(jié)

  1. 當(dāng)用戶自定義了targetSource馆铁,說(shuō)明代理目標(biāo)target由用戶自己負(fù)責(zé)窗口(包括實(shí)例化等步驟)跑揉,因此在bean初始化前就會(huì)調(diào)用AbstractAutoProxyCreatorpostProcessBeforeInstantiation生成代理。生成后的代理已經(jīng)是完整形態(tài),因此历谍,直接調(diào)用postProcessAfterInitialization對(duì)該代理進(jìn)行完善现拒,接著直接返回,進(jìn)行短路操作望侈!不需要再進(jìn)行Spring Ioc創(chuàng)建bean的過(guò)程印蔬!
  2. 當(dāng)用戶沒(méi)自定義targetSource時(shí),那么這個(gè)步驟返回的便是null脱衙,則會(huì)進(jìn)行Spring Ioc創(chuàng)建bean的標(biāo)準(zhǔn)程序侥猬,實(shí)例化、填充屬性捐韩、初始化退唠。并且在postProcessAfterInitialization中調(diào)用wrapIfNecessary進(jìn)行AOP代理

代理時(shí)機(jī)流程圖:


AOP代理時(shí)機(jī)

二、自動(dòng)代理

上面已經(jīng)說(shuō)了荤胁,代理時(shí)機(jī)分為2種瞧预,但是絕大部分情況還是使用的是第二種!也就是在初始化后進(jìn)行AOP代理仅政。上面在初始化后置處理器看到AOP通過(guò)wrapIfNecessary完成

// AbstractAutoProxyCreator.java
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 該bean已經(jīng)處理過(guò)了垢油,則直接返回
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 無(wú)需被增強(qiáng),也跳過(guò)
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        // 如果該bean是基礎(chǔ)類圆丹,或者指定了該bean不需要代理滩愁,則不進(jìn)行代理,跳過(guò)
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // Create proxy if we have advice.
        // 1. 獲取增強(qiáng)攔截器
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        // 存在增強(qiáng)运褪,則進(jìn)行代理
        if (specificInterceptors != DO_NOT_PROXY) {
            // 緩存表明該bean需要被增強(qiáng)
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 2. 創(chuàng)建代理
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        // 緩存表明bean已經(jīng)增強(qiáng)過(guò)
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

1. 獲取增強(qiáng)攔截器

    // AbstractAdvisorAutoProxyCreator.java 
    protected Object[] getAdvicesAndAdvisorsForBean(
            Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
        // 1. 獲取所有Advisor 2. 在所有Advisor中挑選適用的Advisor
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 獲取所有Advisor
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        // 在所有Advisor中尋找適用于該bean的Advisor
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
      // 對(duì)所有Advisor進(jìn)行排序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

1.1 findCandidateAdvisors

    // AnnotationAwareAspectJAutoProxyCreator.java
    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 適用注解方式配置AOP惊楼,但是可能也還存在xml配置的AOP,因此調(diào)用父類方法加載xml中的AOP聲明
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        if (this.aspectJAdvisorsBuilder != null) {
            // 為所有注解了@Aspect類創(chuàng)建增強(qiáng)
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
// BeanFactoryAspectJAdvisorsBuilder.java
public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = this.aspectBeanNames;//- 獲取Aspect切面的beanName

        // 說(shuō)明還沒(méi)有緩存秸讹,需要從頭遍歷所有bean檀咙,找出注解了@Aspect的bean
        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    aspectNames = new ArrayList<>();
                    // 通過(guò)BeanFactory,也就是Ioc容器獲取所有的beanName
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    // 循環(huán)所有beanName
                    for (String beanName : beanNames) {
                        // 不合法的bean直接跳過(guò)璃诀,規(guī)則由子類定義
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // We must be careful not to instantiate beans eagerly as in this case they
                        // would be cached by the Spring container but would not have been weaved.
                        // 獲取bean類型
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        // 該bean被Aspect注解
                        if (this.advisorFactory.isAspect(beanType)) {
                            aspectNames.add(beanName);//- 緩存被Aspect注解的beanName
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            /**
                             * singleton:即切面只會(huì)有一個(gè)實(shí)例弧可;
                             * perthis:每個(gè)切入點(diǎn)表達(dá)式匹配的連接點(diǎn)對(duì)應(yīng)的AOP對(duì)象(代理對(duì)象)都會(huì)創(chuàng)建一個(gè)新切面實(shí)例;
                             * pertarget:每個(gè)切入點(diǎn)表達(dá)式匹配的連接點(diǎn)對(duì)應(yīng)的目標(biāo)對(duì)象都會(huì)創(chuàng)建一個(gè)新的切面實(shí)例
                             */
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                // 解析增強(qiáng)方法
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                if (this.beanFactory.isSingleton(beanName)) {
                                    // 如果bean是單例劣欢,則直接緩存Advisor
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                else {
                                    // 不是單例的情況下棕诵,只能緩存工廠,每次都取增強(qiáng)都得新生產(chǎn)一個(gè)
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                // 添加Advisor
                                advisors.addAll(classAdvisors);
                            }
                            else {
                                // Per target or per this.
                                if (this.beanFactory.isSingleton(beanName)) {
                                    throw new IllegalArgumentException("Bean with name '" + beanName +
                                            "' is a singleton, but aspect instantiation model is not singleton");
                                }
                                MetadataAwareAspectInstanceFactory factory =
                                        new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                                this.aspectFactoryCache.put(beanName, factory);
                                advisors.addAll(this.advisorFactory.getAdvisors(factory));
                            }
                        }
                    }
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }

        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        }
        List<Advisor> advisors = new ArrayList<>();
        for (String aspectName : aspectNames) {
            // 從緩存中獲取增強(qiáng)
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                // 加入到列表中
                advisors.addAll(cachedAdvisors);
            }
            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        return advisors;
    }

1.2 findAdvisorsThatCanApply

    // AbstractAdvisorAutoProxyCreator.java
    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            // 匹配當(dāng)前bean適用的advisors凿将,只匹配到類校套,只有調(diào)用時(shí)JdkDynamicAopProxy.invoke才匹配到方法
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        List<Advisor> eligibleAdvisors = new ArrayList<>();
        //- 處理引介增強(qiáng)
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            //- 處理普通bean
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        if (advisor instanceof IntroductionAdvisor) {
            return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
        }
        else if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pca = (PointcutAdvisor) advisor;
            // 獲取Pointcut跟targetClass做匹配
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
            // It doesn't have a pointcut so we assume it applies.
            return true;
        }
    }

創(chuàng)建代理流程圖:


在這里插入圖片描述

2. 創(chuàng)建代理

創(chuàng)建代理我們已經(jīng)詳解過(guò)ProxyFactory,設(shè)置接口牧抵,設(shè)置代理目標(biāo)笛匙,設(shè)置增強(qiáng)侨把,最后生成代理

    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        // 獲取當(dāng)前類的相關(guān)屬性
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                // 添加代理接口
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        // 設(shè)置增強(qiáng)
        proxyFactory.addAdvisors(advisors);
        // 設(shè)置代理目標(biāo)類
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        // 創(chuàng)建代理,在之前的proxyFactory已經(jīng)詳解過(guò)
        return proxyFactory.getProxy(getProxyClassLoader());
    }

創(chuàng)建代理妹孙,這個(gè)接下去就很熟悉了

    public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秋柄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蠢正,更是在濱河造成了極大的恐慌骇笔,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚣崭,死亡現(xiàn)場(chǎng)離奇詭異笨触,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)有鹿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門旭旭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谎脯,“玉大人葱跋,你說(shuō)我怎么就攤上這事≡此螅” “怎么了娱俺?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)废麻。 經(jīng)常有香客問(wèn)我荠卷,道長(zhǎng),這世上最難降的妖魔是什么烛愧? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任油宜,我火速辦了婚禮,結(jié)果婚禮上怜姿,老公的妹妹穿的比我還像新娘慎冤。我一直安慰自己,他們只是感情好沧卢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布蚁堤。 她就那樣靜靜地躺著,像睡著了一般但狭。 火紅的嫁衣襯著肌膚如雪披诗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天立磁,我揣著相機(jī)與錄音呈队,去河邊找鬼。 笑死唱歧,一個(gè)胖子當(dāng)著我的面吹牛宪摧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绍刮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼温圆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起孩革,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤岁歉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后膝蜈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锅移,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年饱搏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了非剃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡推沸,死狀恐怖备绽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鬓催,我是刑警寧澤肺素,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站宇驾,受9級(jí)特大地震影響倍靡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜课舍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一塌西、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧筝尾,春花似錦捡需、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至贸街,卻和暖如春庵寞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背薛匪。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工捐川, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逸尖。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓古沥,卻偏偏與公主長(zhǎng)得像轿塔,于是被迫代替她去往敵國(guó)和親姆吭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354