01、IOC容器設(shè)計理念與核心注解的使用

一哈街、Spring框架功能整體介紹

1留瞳、SpringCoreContainer

模塊作用: Core 和 Beans 模塊是框架的基礎(chǔ)部分,提供 IoC (轉(zhuǎn)控制)和依賴注入特性骚秦。 這里的基礎(chǔ) 概念是 BeanFactory她倘,它提供對 Factory 模式的經(jīng)典實現(xiàn)來消除對程序性單例模式的需要,并真 正地允許你從程序邏輯中分離出依賴關(guān)系和配置作箍。

1.1)Core模塊

主要包含 Spring 框架基本的核心工具類硬梁, Spring 的其他組件都要用到這個包 里的類, Core模塊是其他組件的基 本核心胞得。

1.2)Beans (BeanFacotry的作用)

它包含訪問配直文件荧止、創(chuàng)建和管理 bean 以及進行 Inversion of Control I Dependency Injection (IoC/DI)操作相關(guān)的所有類。

1.3)Context(處理BeanFactory阶剑,一下還是ApplicationContext的作用)

模構(gòu)建于 Core 和 Beans 模塊基礎(chǔ)之上跃巡,提供了一種類似JNDI 注冊器的框 架式的對象訪問方法。 Context 模塊繼承了 Beans 的特性牧愁,為 Spring 核心提供了大量 擴展瓷炮,添加了對 國際化(例如資源綁定)、事件傳播递宅、資源加載和對 Context 的透明創(chuàng) 建的支持。 Context 模塊同時 也支持 J2EE 的一些特性, ApplicationContext 接口是 Context 模塊的關(guān)鍵
本質(zhì)區(qū)別:使用BeanFacotry的bean是延時加載的,ApplicationContext是非延時加載的

1.4)Expression Language

模塊提供了強大的表達式語言办龄,用于在運行時查詢和操縱對象烘绽。 它是 JSP 2.1 規(guī)范中定義的 unifedexpression language 的擴展。 該語言支持設(shè)直/獲取屬 性的值俐填,屬性的分配安接,方法的調(diào)用,訪問數(shù)組上下文( accessiong the context of arrays )英融、 容器和索引器盏檐、邏輯和算術(shù)運算符、命名變量以及從Spring的 IoC 容器中根據(jù)名稱檢 索對象驶悟。 它也支持 list 投影胡野、選擇和一般的 list 聚合.

2、Spring Data Access/Integration

2.1) JDBC

模塊提供了一個 JDBC 抽象層痕鳍,它可以消除冗長的 JDBC 編碼和解析數(shù)據(jù)庫廠 商特有的錯誤代碼硫豆。這個模塊包含了 Spring 對 JDBC 數(shù)據(jù)訪問進行封裝的所有類。

2.2) ORM 模塊為流行的對象-關(guān)系映射 API

如 JPA笼呆、 JDO熊响、 Hibernate、 iBatis 等诗赌,提供了 一個交互層汗茄。 利用 ORM 封裝包,可以混合使用所有 Spring 提供的特性進行 O/R 映射铭若, 如前邊提到的簡單聲 明性事務(wù)管理洪碳。

2.3) OXM 模塊提供了一個對 ObjecνXML 映射實現(xiàn)的抽象層

Object/XML 映射實現(xiàn)包括 JAXB、 Castor奥喻、 XMLBeans偶宫、 JiBX 和 XStrearn

2.4) JMS ( Java Messaging Service)

模塊主要包含了一些制造和消 費消息的特性。

2.5) Transaction

支持編程和聲明性的事務(wù)管理环鲤,這些事務(wù)類必須實現(xiàn)特定的接口纯趋,并 且對所有的 POJO 都適用

3、Spring Web

Web 模塊:提供了基礎(chǔ)的面向 Web 的集成特性c 例如冷离,多文件上傳吵冒、使用 servlet listeners 初始化
IoC 容器以及一個面向 Web 的應(yīng)用上下文。 它還包含 Spring 遠程支持中 Web 的相關(guān)部分西剥。

4痹栖、Spring Aop

  1. Aspects 模塊提供了對 AspectJ 的集成支持。
  2. Instrumentation 模塊提供了 class instrumentation 支持和 classloader 實現(xiàn)瞭空,使得可以在特
    定的應(yīng)用服務(wù)器上使用

5揪阿、Test

Test 模塊支持使用 JUnit 和 TestNG 對 Spring 組件進行測試

6疗我、Spring 容器繼承圖:

7、依賴注入控制反轉(zhuǎn)

7.1) 什么是控制反轉(zhuǎn)?我覺得有必要先了解軟件設(shè)計的一個重要思想:依賴倒置原則(Dependency Inversion Principle )

①:什么是依賴倒置原則南捂? 假設(shè)我們設(shè)計一輛汽車:先設(shè)計輪子吴裤,然后根據(jù)輪子大小設(shè)計底盤,接著根據(jù)底盤設(shè)計車身溺健,最后根據(jù)車身設(shè)計好整個汽車麦牺。這里就出現(xiàn)了一個“依賴”關(guān)系:汽車依賴車身,車身依賴底盤鞭缭,底盤依賴輪子剖膳。

上圖看上去沒有什么毛病?但是 萬一輪胎尺寸改了,那么地盤需要改,地盤改了岭辣,車身也改了吱晒,讓后整個汽車構(gòu)造都改了.
然后汽車公司倒閉了!!!
....................................................................................................................................................
董事長依賴總經(jīng)理爭取,總經(jīng)理依賴部門經(jīng)理掙錢易结,部門經(jīng)理依賴員工爭取枕荞,那么員工離職了怎么
辦?搞动?躏精?
....................................................................................................................................................
反過來:假如汽車公司決定修改輪胎的 我們就只需要改動輪子的設(shè)計,而不需要動底盤鹦肿,車身矗烛,汽車的設(shè)計了。

IOC容器的最最最最核心思想........................
ioc的思想最核心的地方在于箩溃,資源不由使用資源的雙方管理瞭吃,而由不使用資源的第三方管理,這可以帶來很多好處涣旨。第一歪架,資源集中管理,實現(xiàn)資源的可配置和易管理霹陡。第二和蚪,降低了使用資源雙方的依賴程度,也就是我們說的耦合度烹棉。

二攒霹、Spring IOC 容器底層注解使用

2.1) xml配置文件的形式 VS 配置類的形式

2.1.1) 基于xml的形式定義Bean的信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
   
    //定義一個Bean的信息
    <bean id="car" class="com.tuling.compent.Car"></bean>
</beans>

去容器中讀取bean

public static void main( String[] args ){
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    System.out.println(ctx.getBean("person"));
}
2.1.2) 基于讀取配置類的形式定義Bean信息
@Configuration
public class MainConfig {
    @Bean
    public Person person(){
        return new Person();
    }
}

注意: 通過@Bean的形式是使用的話, bean的默認名稱是方法名浆洗,若@Bean(value="bean的名稱")那么bean的名稱是指定的

去容器中讀取Bean的信息(傳入配置類)

public static void main( String[] args ){
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
    System.out.println(ctx.getBean("person"));
}

2.2) 在配置類上寫@CompentScan注解來進行包掃描

@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"})
public class MainConfig {
}
2.2.1)排除用法 excludeFilters(排除@Controller注解的,和TulingService的)
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"},excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class}),
        @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,value = {TulingService.class})
})
public class MainConfig {
}
2.2.2)包含用法 includeFilters ,注意催束,若使用包含的用法, 需要把useDefaultFilters屬性設(shè)置為false(true表示掃描全部的)
@Configuration
@ComponentScan(basePackages = {"com.tuling.testcompentscan"},includeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION,value = {Controller.class, Service.class})
},useDefaultFilters = false)
public class MainConfig {
}
2.2.3)@ComponentScan.Filter type的類型

a)注解形式的FilterType.ANNOTATION @Controller @Service @Repository @Compent
b)指定類型的 FilterType.ASSIGNABLE_TYPE @ComponentScan.Filter(type =
FilterType.ASSIGNABLE_TYPE,value = {TulingService.class})
c)aspectj類型的 FilterType.ASPECTJ(不常用)
d)正則表達式的 FilterType.REGEX(不常用)
e)自定義的 FilterType.CUSTOM

public enum FilterType {
    //注解形式  比如@Controller @Service @Repository  @Compent
    ANNOTATION,
    //指定的類型
    ASSIGNABLE_TYPE,
    //aspectJ形式的
    ASPECTJ,
    //正則表達式的
    REGEX,
    //自定義的
    CUSTOM
}

FilterType.CUSTOM 自定義類型如何使用

public class TulingFilterType implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        //獲取當前類的注解源信息
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //獲取當前類的class的源信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //獲取當前類的資源信息
        Resource resource =  metadataReader.getResource();
        if(classMetadata.getClassName().contains("dao")) {
            return true;
        }
        return false;
    }
}
@ComponentScan(basePackages = {"com.tuling.testcompentscan"},includeFilters = {
        @ComponentScan.Filter(type = FilterType.CUSTOM,value = TulingFilterType.class)
},useDefaultFilters = false)
public class MainConfig {
}

2.3配置Bean的作用域?qū)ο?/h4>

2.3.1)在不指定@Scope的情況下伏社,所有的bean都是單實例的bean,而且是餓漢加載(容器啟動實例就創(chuàng)建好了)
@Bean
public Person person() {
    return new Person();
}
2.3.2)指定@Scope為 prototype 表示為多實例的抠刺,而且還是懶漢模式加載(IOC容器啟動的時候塔淤,并不會創(chuàng)建對象,而是在第一次使用的時候才會創(chuàng)建)
@Bean
@Scope(value = "prototype")
public Person person() {
    return new Person();
}
2.3.3)@Scope指定的作用域方法取值

a) singleton 單實例的(默認)
b) prototype 多實例的
c) request 同一次請求
d) session 同一個會話級別

2.4)Bean的懶加載@Lazy(主要針對單實例的bean 容器啟動的時候矫付,不創(chuàng)建對象凯沪,在第一次使用的時候才會創(chuàng)建該對象)

@Bean
@Lazy
public Person person() {
    return new Person();
}

2.5)@Conditional進行條件判斷等

場景,有二個組件TulingAspect 和TulingLog ,我的TulingLog組件是依賴于TulingAspect的組件應(yīng)用:自己創(chuàng)建一個TulingCondition的類 實現(xiàn)Condition接口

public class TulingCondition implements Condition {
    /**
     *
     * @param context
     * @param metadata
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //判斷容器中是否有tulingAspect的組件
        if(context.getBeanFactory().containsBean("tulingAspect")) {
            return true;
        }
        return false;
    }
}

public class MainConfig {
    @Bean
    public TulingAspect tulingAspect() {
        return new TulingAspect();
    }
   
    //當切 容器中有tulingAspect的組件买优,那么tulingLog才會被實例化.
    @Bean
    @Conditional(value = TulingCondition.class)
    public TulingLog tulingLog() {
        return new TulingLog();
    }
}

2.6)往IOC 容器中添加組件的方式

①:通過@CompentScan +@Controller @Service @Respository @compent
適用場景: 針對我們自己寫的組件可以通過該方式來進行加載到容器中。
②:通過@Bean的方式來導(dǎo)入組件(適用于導(dǎo)入第三方組件的類)
③:通過@Import來導(dǎo)入組件 (導(dǎo)入組件的id為全類名路徑)

@Configuration
@Import(value = {Person.class, Car.class})
public class MainConfig {
}

通過@Import 的ImportSeletor類實現(xiàn)組件的導(dǎo)入 (導(dǎo)入組件的id為全類名路徑)

public class TulingImportSelector implements ImportSelector {
    /可以獲取導(dǎo)入類的注解信息
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.tuling.testimport.compent.Dog"};
    }
}
@Configuration
@Import(value = {Person.class, Car.class, TulingImportSelector.class})
public class MainConfig {
}

通過@Import的 ImportBeanDefinitionRegister導(dǎo)入組件 (可以指定bean的名稱)

public class TulingBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //創(chuàng)建一個bean定義對象
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Cat.class);
        //把bean定義對象導(dǎo)入到容器中
        registry.registerBeanDefinition("cat",rootBeanDefinition);
    }
}
@Configuration
//@Import(value = {Person.class, Car.class})
//@Import(value = {Person.class, Car.class, TulingImportSelector.class})
@Import(value = {Person.class, Car.class, TulingImportSelector.class, TulingBeanDefinitionRegister.class})
public class MainConfig {
}

④:通過實現(xiàn)FacotryBean接口來實現(xiàn)注冊 組件
使用場景:類的初始化過程比較復(fù)雜的時候挺举,使用該方式(原理:工廠方法模式)

public class CarFactoryBean implements FactoryBean<Car> {
   
    /返回bean的對象
    @Override
    public Car getObject() throws Exception {
        return new Car();
    }
   
    /返回bean的類型
    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }
   
    /是否為單利
    @Override
    public boolean isSingleton() {
        return true;
    }
}

2.7)Bean的初始化方法和銷毀方法.

①:什么是bean的生命周期?
bean的創(chuàng)建----->初始化----->銷毀方法
由容器管理Bean的生命周期杀赢,我們可以通過自己指定bean的初始化方法和bean的銷毀方法

@Configuration
public class MainConfig {
   
    //指定了bean的生命周期的初始化方法和銷毀方法.
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Car car() {
        return new Car();
    }
}

針對單實例bean的話,容器啟動的時候湘纵,bean的對象就創(chuàng)建了脂崔,而且容器銷毀的時候,也會調(diào)用Bean的銷毀方法
針對多實例bean的話,容器啟動的時候梧喷,bean是不會被創(chuàng)建的而是在獲取bean的時候被創(chuàng)建砌左,而且bean的銷毀不受IOC容器的管理.

②:通過 InitializingBean和DisposableBean 的二個接口實現(xiàn)bean的初始化以及銷毀方法

@Component
public class Person implements InitializingBean,DisposableBean {
    public Person() {
        System.out.println("Person的構(gòu)造方法");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean的destroy()方法 ");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean的 afterPropertiesSet方法");
    }
}

③:通過JSR250規(guī)范 提供的注解@PostConstruct 和@ProDestory標注的方法

@Component
public class Book {
    public Book() {
        System.out.println("book 的構(gòu)造方法");
    }
    @PostConstruct
    public void init() {
        System.out.println("book 的PostConstruct標志的方法");
    }
    @PreDestroy
    public void destory() {
        System.out.println("book 的PreDestory標注的方法");
    }
}

④:通過Spring的BeanPostProcessor的 bean的后置處理器會攔截所有bean創(chuàng)建過程
postProcessBeforeInitialization 在init方法之前調(diào)用
postProcessAfterInitialization 在init方法之后調(diào)用

@Component
public class TulingBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("TulingBeanPostProcessor...postProcessBeforeInitialization:"+beanName);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("TulingBeanPostProcessor...postProcessAfterInitialization:"+beanName);
        return bean;
    }
}

BeanPostProcessor的執(zhí)行時機

populateBean(beanName, mbd, instanceWrapper)
initializeBean{
    applyBeanPostProcessorsBeforeInitialization()
    invokeInitMethods{
        isInitializingBean.afterPropertiesSet
        自定義的init方法
    }
    applyBeanPostProcessorsAfterInitialization()方法
}

2.8)通過@Value + @PropertySource來給組件賦值

public class Person {
  
    //通過普通的方式
    @Value("司馬")
    private String firstName;
   
    //spel方式來賦值
    @Value("#{28-8}")
    private Integer age;
    通過讀取外部配置文件的值
    @Value("${person.lastName}")
    private String lastName;
}   

@Configuration
@PropertySource(value = {"classpath:person.properties"}) //指定外部文件的位置
public class MainConfig {
    @Bean
    public Person person() {
        return new Person();
    }
}

2.9)自動裝配

@AutoWired的使用
自動注入:

//一個Dao
@Repository
public class TulingDao {
}
@Service
public class TulingService {
    @Autowired
    private TulingDao tulingDao;
}

結(jié)論:

a:自動裝配首先是按照類型進行裝配,若在IOC容器中發(fā)現(xiàn)了多個相同類型的組件铺敌,那么就按照 屬性名稱來進行裝配

@Autowired
private TulingDao tulingDao;

比如汇歹,我容器中有二個TulingDao類型的組件 一個叫tulingDao 一個叫tulingDao2,那么我們通過@AutoWired 來修飾的屬性名稱時tulingDao偿凭,那么拿就加載容器的tulingDao組件产弹,若屬性名稱為tulignDao2 那么他就加載的時tulingDao2組件

b:假設(shè)我們需要指定特定的組件來進行裝配,我們可以通過使用@Qualifier("tulingDao")來指定裝配的組件或者在配置類上的@Bean加上@Primary注解

@Autowired
    @Qualifier("tulingDao")
    private TulingDao tulingDao2;

c:假設(shè)我們?nèi)萜髦屑礇]有tulingDao 和tulingDao2,那么在裝配的時候就會拋出異常
No qualifying bean of type 'com.tuling.testautowired.TulingDao' available
若我們想不拋異常 弯囊,我們需要指定 required為false的時候可以了

 @Autowired(required = false)
    @Qualifier("tulingDao")
    private TulingDao tulingDao2;

d:@Resource(JSR250規(guī)范)
功能和@AutoWired的功能差不多一樣痰哨,但是不支持@Primary 和@Qualifier的支持

e:@InJect(JSR330規(guī)范)
需要導(dǎo)入jar包依賴
功能和支持@Primary功能 ,但是沒有Require=false的功能

<dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
</dependency>

f:使用autowired 可以標注在方法上
標注在set方法上

//@Autowired
    public void setTulingLog(TulingLog tulingLog) {
        this.tulingLog = tulingLog;
    }

標注在構(gòu)造方法上:

@Autowired
    public TulingAspect(TulingLog tulingLog) {
        this.tulingLog = tulingLog;
    }

標注在配置類的入?yún)⒅校梢圆粚懀?/p>

@Bean
    public TulingAspect tulingAspect(@Autowired TulingLog tulingLog) {
        TulingAspect tulingAspect = new TulingAspect(tulingLog);
        return tulingAspect;
    }

3.0) 我們自己的組件 需要使用spring ioc的底層組件的時候,比如 ApplicationContext等

我們可以通過實現(xiàn)XXXAware接口來實現(xiàn)

@Component
public class TulingCompent implements ApplicationContextAware,BeanNameAware {
    private ApplicationContext applicationContext;
    @Override
    public void setBeanName(String name) {
        System.out.println("current bean name is :【"+name+"】");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

3.1) 通過@Profile注解 來根據(jù)環(huán)境來激活標識不同的Bean

@Profile標識在類上,那么只有當前環(huán)境匹配匾嘱,整個配置類才會生效
@Profile標識在Bean上 斤斧,那么只有當前環(huán)境的Bean才會被激活
沒有標志為@Profile的bean 不管在什么環(huán)境都可以被激活

@Configuration
@PropertySource(value = {"classpath:ds.properties"})
public class MainConfig implements EmbeddedValueResolverAware {
    @Value("${ds.username}")
    private String userName;
    @Value("${ds.password}")
    private String password;
    private String jdbcUrl;
    private String classDriver;
    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}");
        this.classDriver = resolver.resolveStringValue("${ds.classDriver}");
    }
   
    //標識為測試環(huán)境才會被裝配
    @Bean
    @Profile(value = "test")
    public DataSource testDs() {
        return buliderDataSource(new DruidDataSource());
    }
   
    //標識開發(fā)環(huán)境才會被激活
    @Bean
    @Profile(value = "dev")
    public DataSource devDs() {
        return buliderDataSource(new DruidDataSource());
    }
   
    //標識生產(chǎn)環(huán)境才會被激活
    @Bean
    @Profile(value = "prod")
    public DataSource prodDs() {
        return buliderDataSource(new DruidDataSource());
    }
    private DataSource buliderDataSource(DruidDataSource dataSource) {
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(classDriver);
        dataSource.setUrl(jdbcUrl);
        return dataSource;
    }
}

激活切換環(huán)境的方法
方法一:通過運行時jvm參數(shù)來切換 -Dspring.profiles.active=test|dev|prod
方法二:通過代碼的方式來激活

public static void main(String[] args) {
     
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.getEnvironment().setActiveProfiles("test","dev");
    ctx.register(MainConfig.class);
    ctx.refresh();
    printBeanName(ctx);
}
``
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市霎烙,隨后出現(xiàn)的幾起案子撬讽,更是在濱河造成了極大的恐慌,老刑警劉巖吼过,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锐秦,死亡現(xiàn)場離奇詭異,居然都是意外死亡盗忱,警方通過查閱死者的電腦和手機酱床,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趟佃,“玉大人扇谣,你說我怎么就攤上這事昧捷。” “怎么了罐寨?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵靡挥,是天一觀的道長。 經(jīng)常有香客問我鸯绿,道長跋破,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任瓶蝴,我火速辦了婚禮毒返,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舷手。我一直安慰自己拧簸,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布男窟。 她就那樣靜靜地躺著盆赤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歉眷。 梳的紋絲不亂的頭發(fā)上牺六,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音姥芥,去河邊找鬼兔乞。 笑死,一個胖子當著我的面吹牛凉唐,可吹牛的內(nèi)容都是我干的庸追。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼台囱,長吁一口氣:“原來是場噩夢啊……” “哼淡溯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起簿训,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤咱娶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后强品,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膘侮,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年的榛,在試婚紗的時候發(fā)現(xiàn)自己被綠了琼了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖雕薪,靈堂內(nèi)的尸體忽然破棺而出昧诱,到底是詐尸還是另有隱情,我是刑警寧澤所袁,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布盏档,位于F島的核電站,受9級特大地震影響燥爷,放射性物質(zhì)發(fā)生泄漏蜈亩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一局劲、第九天 我趴在偏房一處隱蔽的房頂上張望勺拣。 院中可真熱鬧,春花似錦鱼填、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至苇经,卻和暖如春赘理,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扇单。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工商模, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜘澜。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓施流,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鄙信。 傳聞我的和親對象是個殘疾皇子瞪醋,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359