spring framwork5-Core Technologies系列

spring官方参考文档的这一部分涵盖了Spring框架绝对不可或缺的所有技术。散人闲来无事,做个知识的搬运工。此系列会陆续更新,有错误的地方欢迎探讨。(发现对代码的兼容性不是很好,见谅<->_<->)

1.The IoC Container 控制反转容器

1.1. Introduction to the Spring IoC Container and Beans

springioc容器和bean简介

This chapter covers Spring’s Inversion of Control (IoC) container.

本章介绍Spring的控制反转(inversionofcontrol,IoC)容器。

This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.

本章介绍控制反转(IoC)原则的Spring框架实现。IoC也称为依赖注入(dependency injection,DI)。这是一个过程,在这个过程中,对象只通过构造函数参数、工厂方法的参数或在对象实例构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖项(即它们使用的其他对象)。然后容器在创建bean时注入这些依赖项。这个过程基本上与bean本身相反(因此称为控制反转),它使用类的直接构造或服务定位器模式等机制来控制其依赖项的实例化或位置。

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

这个org.springframework.beans以及org.springframework.context包是Spring框架的IoC容器的基础。BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。ApplicationContext是BeanFactory的一个子接口。它补充了:

1,Easier integration with Spring’s AOP features
更容易与Spring的AOP特性集成
2,Message resource handling (for use in internationalization)
消息资源处理(用于国际化)
3,Event publication
事件发布
4,Application-layer specific contexts such as the WebApplicationContext for use in web applications.
特定于应用程序层的上下文,如用于web应用程序的WebApplicationContext。

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using the BeanFactory instead of the ApplicationContext, see The BeanFactory.

简而言之,BeanFactory提供了配置框架和基本功能,而ApplicationContext则添加了更多特定于企业的功能。ApplicationContext是BeanFactory的一个完整的超集,在本章中专门用于描述Spring的IoC容器。有关使用BeanFactory而不是ApplicationContext的更多信息,请参阅The BeanFactory

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

在Spring中,构成应用程序主干并由springioc容器管理的对象称为bean。bean是由springioc容器实例化、组装和管理的对象。否则,bean只是应用程序中众多对象中的一个。bean以及它们之间的依赖关系反映在容器使用的配置元数据中。

1.2. Container Overview

容器概述

The* org.springframework.context.ApplicationContext* interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.

org.springframework.context.ApplicationContext接口表示SpringIoC容器,是负责实例化、配置和组装bean。容器通过读取配置元数据获取有关实例化、配置和组装哪些对象的指令。配置元数据可以用XML、Java注释或Java代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。

Several implementations of the ApplicationContext interface are supplied with Spring. In stand-alone applications, it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. While XML has been the traditional format for defining configuration metadata, you can instruct the container to use Java annotations or code as the metadata format by providing a small amount of XML configuration to declaratively enable support for these additional metadata formats.

Spring提供了“ApplicationContext”接口的几个实现。在独立应用程序中,创建 ClassPathXmlApplicationContext 的实例或者FileSystemXmlApplicationContext.是常见的。 虽然XML是定义配置元数据的传统格式,但是您可以通过提供少量的XML配置来指示容器使用Java注释或代码作为元数据格式,以声明方式启用对这些附加元数据格式的支持。

In most application scenarios, explicit user code is not required to instantiate one or more instances of a Spring IoC container. For example, in a web application scenario, a simple eight (or so) lines of boilerplate web descriptor XML in the web.xml file of the application typically suffices (see Convenient ApplicationContext Instantiation for Web Applications). If you use the Spring Tools for Eclipse (an Eclipse-powered development environment), you can easily create this boilerplate configuration with a few mouse clicks or keystrokes.

在大多数应用程序场景中,不需要显式用户代码来实例化springioc容器(上下文context)的一个或多个实例。例如,在web应用程序场景中,在web.xml文件应用程序的文件通常就足够了(请参阅Web应用程序的便捷应用程序上下文实例化)。如果您使用Eclipse的Spring工具(一个Eclipse驱动的开发环境),只需单击几次鼠标或击键,就可以轻松地创建这个样板配置。

The following diagram shows a high-level view of how Spring works. Your application classes are combined with configuration metadata so that, after the ApplicationContext is created and initialized, you have a fully configured and executable system or application.

下面的图表展示了Spring如何工作的高级视图。应用程序类与配置元数据相结合,这样,在创建和初始化ApplicationContext之后,您就拥有了一个完全配置并可执行的系统或应用程序。

image

Figure 1. The Spring IoC container

1.2.1. Configuration Metadata 配置元数据

As the preceding diagram shows, the Spring IoC container consumes a form of configuration metadata. This configuration metadata represents how you, as an application developer, tell the Spring container to instantiate, configure, and assemble the objects in your application.

如上图所示,springioc容器使用一种形式的配置元数据。这个配置元数据表示作为应用程序开发人员,如何告诉Spring容器实例化、配置和组装应用程序中的对象。

Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is what most of this chapter uses to convey key concepts and features of the Spring IoC container.

传统上,配置元数据是以简单直观的XML格式提供的,这也是本章大部分内容用来传达springioc容器的关键概念和特性的。

XML-based metadata is not the only allowed form of configuration metadata. The Spring IoC container itself is totally decoupled from the format in which this configuration metadata is actually written. These days, many developers choose Java-based configuration for their Spring applications.

基于XML的元数据不是配置元数据的唯一允许形式。springioc容器本身与实际编写配置元数据的格式完全分离。现在,许多开发人员为他们的Spring应用程序选择基于Java的配置。

For information about using other forms of metadata with the Spring container, see:

有关在Spring容器中使用其他形式的元数据的信息,请参见:

Annotation-based configuration: Spring 2.5 introduced support for annotation-based configuration metadata.

基于注释的配置:Spring2.5引入了对基于注释的配置元数据的支持。

Java-based configuration: Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part of the core Spring Framework. Thus, you can define beans external to your application classes by using Java rather than XML files. To use these new features, see the @Configuration, @Bean, @Import, and @DependsOn annotations.

基于Java的配置:从spring3.0开始,spring javaconfig项目提供的许多特性成为Spring核心框架的一部分。因此,您可以使用Java而不是XML文件来定义应用程序类外部的bean。要使用这些新特性,请参阅@Configuration、@Bean、@Import和@DependsOn注释

Spring configuration consists of at least one and typically more than one bean definition that the container must manage. XML-based configuration metadata configures these beans as <bean/> elements inside a top-level <beans/> element. Java configuration typically uses @Bean-annotated methods within a @Configuration class.

Spring配置至少包含一个bean definition让容器必须管理的,通常不止一个。基于XML的配置元数据将这些bean配置为顶层<beans/>元素中的<bean/>元素。Java配置通常在@configuration类中使用@Bean注释的方法

These bean definitions correspond to the actual objects that make up your application. Typically, you define service layer objects, data access objects (DAOs), presentation objects such as Struts Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so forth. Typically, one does not configure fine-grained domain objects in the container, because it is usually the responsibility of DAOs and business logic to create and load domain objects. However, you can use Spring’s integration with AspectJ to configure objects that have been created outside the control of an IoC container. See Using AspectJ to dependency-inject domain objects with Spring.

这些beandefinition对应于组成应用程序的实际对象。通常,您需要定义服务层对象(service)、数据访问对象(dao)、表示层对象(如Struts Action)、基础结构对象(如Hibernate SessionFactories、JMS队列等)。通常,不在容器中配置细粒度的域对象(domain对象)(也叫entity对象),因为创建和加载域对象通常由dao和业务逻辑负责。但是,您可以使用Spring与AspectJ的集成来配置在IoC容器控制之外创建的对象。请参阅使用AspectJ对Spring进行依赖注入域对象。

The following example shows the basic structure of XML-based configuration metadata:

以下示例显示基于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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>
    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
        <!--这里是这个bean的协作者和配置 -->        
    </bean>
    <!-- more bean definitions go here -->
</beans>

The id attribute is a string that identifies the individual bean definition.

id属性是标识单个bean定义的字符串。

The class attribute defines the type of the bean and uses the fully qualified classname.

class属性定义bean的类型并使用完全限定的类名

The value of the id attribute refers to collaborating objects. The XML for referring to collaborating objects is not shown in this example. See Dependencies for more information.

id属性的值引用协作对象。本例中没有显示用于引用协作对象的XML。有关详细信息,请参见依赖项。

1.2.2. Instantiating a Container 实例化一个容器

The location path or paths supplied to an ApplicationContext constructor are resource strings that let the container load configuration metadata from a variety of external resources, such as the local file system, the Java CLASSPATH, and so on.

提供给“ApplicationContext”构造函数的一个或多个位置路径是资源字符串,允许容器从各种外部资源(如本地文件系统、Java“CLASSPATH”)加载配置元数据。

ApplicationContext context=new ClassPathXmlApplicationContext("services.xml","daos.xml");

After you learn about Spring’s IoC container, you may want to know more about Spring’s Resource abstraction (as described in Resources), which provides a convenient mechanism for reading an InputStream from locations defined in a URI syntax. In particular, Resource paths are used to construct applications contexts, as described in Application Contexts and Resource Paths.

在了解了Spring的IoC容器之后,您可能想进一步了解Spring的资源抽象(如参考资料中所述),它为从URI语法中定义的位置读取InputStream提供了一种方便的机制。特别是,资源路径用于构造应用程序上下文,如应用程序上下文和资源路径中所述

The following example shows the service layer objects (services.xml) configuration file:

下面的示例显示了服务层对象(services.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- services -->
    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>
    <!-- more bean definitions for services go here -->
</beans>

The following example shows the data access objects daos.xml file:

以下示例显示数据访问对象daos.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountDao"
        class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for data access objects go here -->

</beans>

In the preceding example, the service layer consists of the PetStoreServiceImpl class and two data access objects of the types JpaAccountDao and JpaItemDao (based on the JPA Object-Relational Mapping standard). The property name element refers to the name of the JavaBean property, and the ref element refers to the name of another bean definition. This linkage between id and ref elements expresses the dependency between collaborating objects. For details of configuring an object’s dependencies, see Dependencies.

在前面的示例中,服务层由PetStoreServiceImpl类和两个JpaAccountDao和JPAIItemDAO类型的数据访问对象(基于JPA对象关系映射标准)组成。property name元素引用JavaBean属性的名称,ref元素引用另一个bean定义的名称。id和ref元素之间的这种链接表示协作对象之间的依赖关系。有关配置对象依赖项的详细信息,请参见依赖项。

Composing XML-based Configuration Metadata

基于XML的配置元数据的合成

It can be useful to have bean definitions span multiple XML files. Often, each individual XML configuration file represents a logical layer or module in your architecture.

bean定义跨越多个XML文件可能很有用。通常,每个单独的XML配置文件都表示体系结构中的逻辑层或模块。

You can use the application context constructor to load bean definitions from all these XML fragments. This constructor takes multiple Resource locations, as was shown in the previous section. Alternatively, use one or more occurrences of the <import/> element to load bean definitions from another file or files. The following example shows how to do so:

您可以使用应用程序上下文构造函数从所有这些XML片段加载bean定义。这个构造函数接受多个资源位置,如前一节所示。或者,使用<import/>元素的一个或多个引用从另一个文件或文件加载bean定义。以下示例显示如何执行此操作:

<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

In the preceding example, external bean definitions are loaded from three files: services.xml, messageSource.xml, and themeSource.xml. All location paths are relative to the definition file doing the importing, so services.xml must be in the same directory or classpath location as the file doing the importing, while messageSource.xml and themeSource.xml must be in a resources location below the location of the importing file. As you can see, a leading slash is ignored. However, given that these paths are relative, it is better form not to use the slash at all. The contents of the files being imported, including the top level <beans/> element, must be valid XML bean definitions, according to the Spring Schema.

在前面的示例中,外部bean定义从三个文件加载:service.xml,messageSource.xml,和themeSource.xml. 所有位置路径都与执行导入的定义文件相关,因此services.xml必须与执行导入的文件位于相同的目录或类路径位置,而messageSource.xml以及themeSource.xml必须位于导入文件位置下方的资源位置。如您所见,正斜杠被忽略。但是,考虑到这些路径是相对的,最好不要使用斜杠。根据Spring模式,导入的文件的内容(包括顶层的<beans/>元素)必须是有效的xmlbean定义。

It is possible, but not recommended, to reference files in parent directories using a relative "../" path. Doing so creates a dependency on a file that is outside the current application. In particular, this reference is not recommended for classpath: URLs (for example, classpath:../services.xml), where the runtime resolution process chooses the “nearest” classpath root and then looks into its parent directory. Classpath configuration changes may lead to the choice of a different, incorrect directory. You can always use fully qualified resource locations instead of relative paths: for example, file:C:/config/services.xml or classpath:/config/services.xml. However, be aware that you are coupling your application’s configuration to specific absolute locations. It is generally preferable to keep an indirection for such absolute locations — for example, through "${…}" placeholders that are resolved against JVM system properties at runtime.

可以(但不建议)使用相对“../”路径引用父目录中的文件。这样做会对当前应用程序之外的文件产生依赖关系。特别是,不建议将此引用用于classpath:url(例如,classpath:../services.xml),运行时解析进程选择“最近的”classpath root(根),然后查找其父目录。类路径配置更改可能导致选择不同的、不正确的目录。

您可以始终使用完全限定的资源位置而不是相对路径:例如,file:C:/config/services.xml或classpath:/config/services.xml.. 但是,请注意,您将应用程序的配置耦合到特定的绝对位置。通常情况下,最好保持这种绝对位置的间接寻址,例如,通过在运行时根据JVM系统属性解析的“${…}”占位符。

The namespace itself provides the import directive feature. Further configuration features beyond plain bean definitions are available in a selection of XML namespaces provided by Spring — for example, the context and util namespaces.

命名空间本身提供了import指令功能。除了普通bean定义之外,还可以在Spring - 提供的一系列XML名称空间中使用其他配置特性,例如context和util名称空间。

The Groovy Bean Definition DSL
As a further example for externalized configuration metadata, bean definitions can also be expressed in Spring’s Groovy Bean Definition DSL, as known from the Grails framework. Typically, such configuration live in a ".groovy" file with the structure shown in the following example:

作为外部化配置元数据的进一步示例,bean定义也可以用Spring的groovy bean definition dsl来表示,正如Grails框架中所说的那样。通常,此类配置位于“.groovy”文件中,其结构如以下示例所示:

beans {
    dataSource(BasicDataSource) {
        driverClassName = "org.hsqldb.jdbcDriver"
        url = "jdbc:hsqldb:mem:grailsDB"
        username = "sa"
        password = ""
        settings = [mynew:"setting"]
    }
    sessionFactory(SessionFactory) {
        dataSource = dataSource
    }
    myService(MyService) {
        nestedBean = { AnotherBean bean ->
            dataSource = dataSource
        }
    }
}

This configuration style is largely equivalent to XML bean definitions and even supports Spring’s XML configuration namespaces. It also allows for importing XML bean definition files through an importBeans directive.

这种配置风格在很大程度上等同于xmlbean定义,甚至支持Spring的XML配置名称空间。它还允许通过importBeans指令导入xmlbean定义文件。

1.2.3. Using the Container

The ApplicationContext is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. By using the method T getBean(String name, Class<T> requiredType), you can retrieve instances of your beans.

ApplicationContext是一个高级工厂的接口,它能够维护不同bean及其依赖项的注册表。通过使用方法getBean(String name,Class<T>requiredType),您可以检索bean的实例。

The ApplicationContext lets you read bean definitions and access them, as the following example shows:

ApplicationContext允许您读取bean定义并访问它们,如下例所示:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();

With Groovy configuration, bootstrapping looks very similar. It has a different context implementation class which is Groovy-aware (but also understands XML bean definitions). The following example shows Groovy configuration:

使用Groovy配置,引导看起来非常相似。它有一个不同的上下文实现类,它支持Groovy(但也理解xmlbean定义)。以下示例显示Groovy配置:

 ApplicationContext context=new GenericGroovyApplicationContext("services.groovy","daos.groovy");

The most flexible variant is GenericApplicationContext in combination with reader delegates — for example, with XmlBeanDefinitionReader for XML files, as the following example shows:

最灵活的变体是GenericApplicationContext与reader delegates - - 的组合,例如,使用XmlBeanDefinitionReader for XML文件,如下例所示:

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();

You can also use the GroovyBeanDefinitionReader for Groovy files, as the following example shows:

您还可以将GroovyBeanDefinitionReader用于Groovy文件,如下例所示:

GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();

You can mix and match such reader delegates on the same ApplicationContext, reading bean definitions from diverse configuration sources.

您可以在同一个ApplicationContext上混合和匹配这样的读卡器委托,从不同的配置源读取bean定义。

You can then use getBean to retrieve instances of your beans. The ApplicationContext interface has a few other methods for retrieving beans, but, ideally, your application code should never use them. Indeed, your application code should have no calls to the getBean() method at all and thus have no dependency on Spring APIs at all. For example, Spring’s integration with web frameworks provides dependency injection for various web framework components such as controllers and JSF-managed beans, letting you declare a dependency on a specific bean through metadata (such as an autowiring annotation).

然后可以使用getBean检索bean的实例。ApplicationContext接口有一些用于检索bean的其他方法,但是理想情况下,您的应用程序代码不应该使用它们。实际上,您的应用程序代码根本不应该调用getBean()方法,因此完全不依赖于SpringAPI。例如,Spring与web框架的集成为各种web框架组件(如controllers和JSF-managed beans)提供了依赖注入,允许您通过元数据(比如自动连接注释)声明对特定bean的依赖性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339