Spring Boot (1.3.6.RELEASE) 入门

本文翻译自Spring Boot官方文档的Getting Started部分,原文可点击此处查看。

如果你刚开始学习使用Spring Boot,或者Spring框架,那么这篇文章正是为你准备的!通过这篇文章,我们将介绍关于Spring Boot的一些基本知识。你将从接下来的章节中了解到Spring Boot的安装命令,我们将一起构建我们的第一个Spring Boot应用,然后我们将一起讨论一些核心原则。

Spring Boot简介

Spring Boot可以帮助我们轻易创建出可独立运行的,基于Spring的生产级应用,这些应用甚至可以直接运行而不依赖其他环境(仅需要JVM)。我们用统一的方式来看待Spring平台以及第三方库,因此你在使用的过程中不会有太多混乱的情况出现,并且大部分Spring Boot应用几乎不需要处理烦人的Spring配置。
使用Spring Boot你可以创建一个可直接用java -jar命令运行的包,当然也可以创建传统的war包,我们还提供了一个命令行工具用来运行“spring脚本”。

我们的主要目的是:

  • 提供一个急速的并且随手可得的Spring项目开发体验。
  • 提供稳定的开箱即得的开发方式,同时又能迅速的在默认配置的基础上做出按需的配置。
  • 提供大量的公共的非功能性特性(例如:嵌入式服务器,权限管理,性能监控,健康检查,外部配置等)。
  • 绝对不需要代码生成并且不需要XML配置文件。

系统要求

默认情况下Spring Boot 1.3.6.RELEASE要求Java 7和Spring Framework 4.2.7.RELEASE或更高版本。你也可以使用Java 6,但是需要一些额外的配置。我们为Maven (3.2+)和Gradle (1.12+)提供了构建支持。

虽然你可以在Java 6或Java 7环境下使用Spring Boot,但我们通常建议如果有可能尽量使用Java 8。

Servlet容器

默认包含下列嵌入式服务器:

Name Servlet Version Java Version
Tomcat 8 3.1 Java 7+
Tomcat 7 3.0 Java 6+
Jetty 9 3.1 Java 7+
Jetty 8 3.0 Java 6+
Undertow 1.1 3.1 Java 7+

你可以将Spring Boot应用部署到任何的Servlet 3.0+兼容的容器中。

安装Spring Boot

Spring Boot可以使用“传统”的Java开发工具或者作为一个命令行工具安装。但无论如何,你需要Java SDK v1.6以上的开发环境。 你可以用以下命名来查看你的Java版本:

$ java -version

如果你是一个Java开发的新手或者你只是想体验一下Spring Boot,你可能首先想试试Spring Boot CLI,你也可以继续阅读下面的内容来了解“传统”方式的使用。

虽然Spring Boot兼容Java 1.6,但如果可能的话,请尽量使用最新版本的Java环境。

安装指令

你可以像任何标准的Java库一样的方式使用Spring Boot,只需要简单的将相关的spring-boot-*.jar文件引入到你的classpath中。Spring Boot不要求任何特殊的工具集成,所以你可以使用任何IDE或者文本编辑器,Spring Boot应用没有任何特殊的地方,所以你可以像其他Java程序一样运行和调试。
虽然你* 可以 *简单的把Spring Boot的jar文件复制到你的项目中,但通常的做法是使用一些支持依赖管理的构建工具(例如Maven或者Gradle)。

Maven安装

Spring Boot兼容Apache Maven 3.2或更高版本。如果你没有安装Maven,你可以按照maven.apache.org中的方法安装。

在很多操作系统上都可以通过相应的包管理器来安装Maven。如果你是OSX Homebrew的用户,你可以通过命令brew install maven来安装,而Ubuntu用户可以运行sudo apt-get install maven来安装。

Spring Boot的依赖使用org.springframework.boot作为groupId,通常你的Maven POM文件需要继承自spring-boot-starter-parent项目,然后声明一个或多个“Starter POMs”依赖。Spring Boot还提供了一个可选的Maven plugin用来创建可执行的jar包。

一个常规的pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>myproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- 继承Spring Boot默认配置 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.6.RELEASE</version>
    </parent>

    <!-- 添加一个典型的web项目配置 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!-- 可执行jar包打包插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

使用spring-boot-starter-parent是一个使用Spring Boot非常好的方式,但并不总是所有情况下都是最适合的方式,有时你可能需要你的项目继承自其它的父项目POM,或者你只是单纯的不喜欢我们的POM设置,我们下面有专门的一个章节来介绍不依赖我们的父项目POM如何使用Spring Boot。

Gradle安装

Spring Boot兼容Gradle 1.12或更高版本。如果你还没有安装Gradle,你可以按照www.gradle.org/中的方法安装。
Spring Boot依赖使用org.springframework.boot作为group
通常你的项目需要声明一个或多个“Starter POMs”依赖。Spring Boot提供了一个Gradle plugin来帮助你创建可执行的jar包。

Gradle Wrapper

Gradle Wrapper提供了一个很优雅的方式将Gradle“包含”到你需要编译的项目中,它是一个可以和代码一起提交的小型的脚本和库,帮助你启动一个编译进程。详情参看这里

一个常规的build.gradle文件如下:

buildscript { 
    repositories { 
        jcenter() 
        maven { url "http://repo.spring.io/snapshot" } 
        maven { url "http://repo.spring.io/milestone" } 
    } 
    dependencies { 
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE") 
    }
}

apply plugin: 'java'
apply plugin: 'spring-boot'

jar { 
    baseName = 'myproject' version = '0.0.1-SNAPSHOT'
}

repositories { 
    jcenter() 
    maven { url "http://repo.spring.io/snapshot" } 
    maven { url "http://repo.spring.io/milestone" }
}

dependencies { 
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("org.springframework.boot:spring-boot-starter-test")
}

安装Spring Boot CLI

Spring Boot CLI是一个命令行工具,可以帮助你快速建立Spring项目原型。它允许你运行Groovy脚本,与Java语法类似但不需要太多的脚手架式的语法。

你并不需要在你的Spring Boot项目中使用CLI工具,但它绝对是落地一个Spring应用最快的方式。

手动安装

你可以在下面的Spring软件源地址下载Spring CLI:

你也可以选择最前沿的snapshot分发包

下载完成后的压缩包中可以找到INSTALL.txt,按照其中的指令进行安装。大体上如下:在.zip文件的bin/目录下有一个spring脚本(Windows下是spring.bat),或者你也可以直接通过java -jar命令运行.jar文件(使用上述的脚本可以帮助你确保classpath正确设置) 。

使用SDKMAN! 安装

SDKMAN! (The Software Development Kit Manager)可以用来管理多种SDK的多个版本,包括Groovy和Spring Boot CLI。从sdkman.io获取SDKMAN!然后通过下面的命令来安装Spring Boot:

$ sdk install springboot
$ spring --version
Spring Boot v1.3.6.RELEASE

如果你在开发有关CLI的特性,并且想要方便的获取你刚刚构建的版本,可以使用下面的额外指令:

$ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-boot-cli-1.3.6.RELEASE-bin/spring-1.3.6.RELEASE/
$ sdk default springboot dev
$ spring --version
Spring CLI v1.3.6.RELEASE

这将会安装一个名叫dev实例的spring本地实例,这个实例指向你的目标构建路径,这样你每次重新构建Spring Boot,spring命令就会保持同步更新了。
你可以用下面的命令来查看:

$ sdk ls springboot
================================================================================
Available Springboot Versions
================================================================================
> + dev* 1.3.6.RELEASE
================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

OSX Homebrew安装

如果你在使用Mac并且使用Homebrew,安装Spring Boot CLI需要做的所有事情就是运行下面的命令:

$ brew tap pivotal/tap
$ brew install springboot

Homebrew会将spring安装到/usr/local/bin

如果你找不到这个formula,可能你安装的brew过期了,运行brew update然后重试。

MacPorts installation

如果你使用Mac并且使用MacPorts, 安装Spring Boot CLI需要做的所有事情就是运行下面的命令:

$ sudo port install spring-boot-cli

命令行自动补全

Spring Boot CLI有一个配套的脚本为BASHzsh提供了自动补全功能。 你可以在任意的shell中用source来执行这个脚本(同样名叫spring),或者将其放在你个人或者系统级的bash自动补全初始化目录中。在Debian系统中,系统级的脚本位于/shell-completion/bash中,当启动一个新的shell时,目录中的脚本会全部执行。你可以手动运行这个脚本,例如你使用SDKMAN!安装的话,就使用以下的命令:

$ . ~/.sdkman/springboot/current/shell-completion/bash/spring
$ spring <HIT TAB HERE>
  grab help jar run test version

如果你使用Homebrew或MacPorts安装Spring Boot CLI,命令行自动补全脚本会自动注册到你的shell中。

快速创建一个Spring CLI示例

你可以使用这里的一个非常简单的web应用来测试你的安装。创建一个名为app.groovy的文件:

@RestController
class ThisWillActuallyRun { 

    @RequestMapping("/") 
    String home() { 
        "Hello World!" 
    }

}

然后在shell中运行:

$ spring run app.groovy

如果你第一次运行,会花费一些时间来下载依赖,后面再次运行的时候会快的多。

在你最喜欢的浏览器中打开localhost:8080然后你应该能看到下面的输出:

Hello World!

从早期的Spring Boot版本升级

如果你正在从早期的Spring Boot发行版升级,查看project wiki上的“release notes”。你会在每个发行版本的“new and noteworthy”特性列表旁边找到升级的指令。

要升级已经存在的CLI,请使用相应的包管理器命令(例如brew upgrade),或者如果你的CLI是手动安装的,参考标准指令,记得更新你的PATH环境变量,清除老旧的引用地址。

开发你的第一个Spring Boot应用

现在我们来开发一个简单的“Hello World” Java web应用,并且用上一些Spring Boot的关键特性。我们会使用Maven来构建这个项目,大部分的IDE都支持Maven。

网址spring.io下包含了很多使用了Spring Boot的“Getting Started”指南,如果你在寻找特定问题的解决方案,你可以先去那里看看。你可以从这个网址start.spring.io进入来简化步骤,在依赖搜索中选择web starter,这将自动生成一个新的项目结构,这样你就可以直接开始编码。 你还可以查看详细文档

在开始之前,打开一个终端并验证你的Java和Maven版本:

$ java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
$ mvn -v
Apache Maven 3.2.3 (33f8c3e1027c3ddde99d3cdebad2656a31e8fdf4; 2014-08-11T13:58:10-07:00)
Maven home: /Users/user/tools/apache-maven-3.1.1
Java version: 1.7.0_51, vendor: Oracle Corporation

你需要为这个示例创建一个单独的目录,后续的所有指令都假设你创建了合适的目录,并且你的“当前目录”就在你的项目目录中。

创建POM

我们需要创建一个Maven pom.xml文件,这个pom.xml文件将作为你项目的构建配置。打开你最常用的文本编辑器然后添加如下内容:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.example</groupId> 
    <artifactId>myproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-parent</artifactId> 
        <version>1.3.6.RELEASE</version> 
    </parent> 

    <!-- Additional lines to be added here... -->

</project>

这样你就有了一个可以构建的项目,你可以运行mvn package来测试(你现在可以暂时忽略“jar will be empty - no content was marked for inclusion!”的警告信息)。

这时候你就可以把项目导入一个IDE了(大部分现代Java IDE都内置了Maven的支持)。但为了简单起见,我们接下来还是使用纯文本编辑器来操作这个示例。

添加classpath依赖

Spring Boot提供了大量的“Starter POMs”,让你可以很方便的添加需要的jar包到你的classpath。我们的示例程序已经在POM的parent中使用了spring-boot-starter-parent,这是一个特殊的starter,它提供了很多有用的默认Maven配置,以及依赖管理的支持,使得你在使用一些依赖的时候可以省略version版本号。

其他的“Starter POMs”可以让我们很方便的使用开发某种特定应用时需要的依赖。如果我们想开发一个web应用,我们就引入一个spring-boot-starter-web的依赖,在这之前我们先来看看我们现在已经引入的依赖:

$ mvn dependency:tree

[INFO] com.example:myproject:jar:0.0.1-SNAPSHOT

mvn dependency:tree命令可以打印出你的项目的依赖树,如你所见spring-boot-starter-parent自身并没有提供任何的依赖包,我们现在编辑我们的pom.xml,加进spring-boot-starter-web依赖:

<dependencies> 
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency>
</dependencies>

如果你再次运行mvn dependency:tree命令,你会发现现在出现了一些新的依赖,包括Tomcat和Spring Boot。

敲代码

为了完成我们的应用,我们需要创建一个Java文件。Maven默认会从src/main/java中找到源代码并编译,所以你需要按照这个格式创建目录结构,然后添加一个叫做src/main/java/Example.java的文件:

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

    @RequestMapping("/")
    String home() { 
        return "Hello World!"; 
    } 

    public static void main(String[] args) throws Exception { 
        SpringApplication.run(Example.class, args); 
    }

}

这里没有多少代码,后面还会添加很多代码进来,但现在让我们从最重要的部分开始吧。

注解@RestController和@RequestMapping

我们的Example类里面的第一个注解是@RestController,它是一个构造型(stereotype)注解,用来标记并且告诉Spring这个类扮演一个特殊的角色,在这个例子里面,我们的类是一个web应用的@Controller,当Spring要处理web请求的时候会找到这个类。

下面的@RequestMapping注解标注路由(routing)信息,用来告诉Spring任何路径为“/”的HTTP请求应该被映射到home方法上。因为类被标注了@RestController注解所以这里方法返回的字符串会被Spring直接原封不动的传递给请求者。

这里的@RestController@RequestMapping注解是Spring MVC提供的注解(它们并不是由Spring Boot提供的特殊注解),参考MVC相关文档

注解@EnableAutoConfiguration

上面的第二类级注解是@EnableAutoConfiguration,这个注解会让Spring Boot基于你已添加的jar依赖来“猜测”你想怎么样来配置Spring。如果你添加了spring-boot-starter-web因此引入了Tomcat和Spring MVC的依赖,自动配置系统会假设你要开发一个web应用并依此帮你配置好Spring。

Starter POMs和自动配置(Auto-Configuration)

自动配置在设计上跟“Starter POMs”十分契合,但这两个概念并没有直接绑定关系,你可以自由的选择外部jar依赖,Spring Boot还是可以很好帮助你自动配置你的应用。

“main”方法

我们的应用最后一部分是main方法,这是一个遵循Java惯例的标准应用入口方法,我们的main方法通过执行run方法代理了Spring Boot的SpringApplication类。SpringApplication将会运行我们的应用,启动自动配置的Tomcat服务器。我们需要将Example.class作为参数传入run方法,以告诉Spring这是我们的首选组件,命令行参数也会通过args数组传入。

运行示例

到这里我们的应用应该可以顺利运行了,如果我们使用了spring-boot-starter-parent的POM,我们将会有一个非常有用的run goal,可以用来直接启动我们的应用,在项目根目录键入命令mvn spring-boot:run来启动应用:

$ mvn spring-boot:run

  .   ____          _            __ _ _
 /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\
( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\
 \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot :: (v1.3.6.RELEASE)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.222 seconds (JVM running for 6.514)

打开浏览器并访问localhost:8080你应该可以看到如下的输出:

Hello World!

如果想退出应用可以按ctrl-c

创建一个可执行jar文件

让我们创建一个完全自包含的并且可以在生产环境运行的可执行jar文件,以此来结束我们的示例。可执行jar(有时也称为“fat jar”)是一个包含了运行应用所需的所有依赖的包文件。

可执行jar和Java

Java没有提供任何标准的机制来加载嵌套的jar文件(jar包中包含了其他jar文件),如果你想要分发一个自包含的应用,这将成为一个阻碍。

为了解决这个问题,很多开发者使用“超级”jar,简单的从所有jar文件中取出所有类并一起打包在一个单独的jar文件中。这种做法存在的问题是你很难弄清楚你的应用实际上在使用的是哪个库,如果不同的jar中存在同名的文件(但内容不同)也将带来潜在的问题。

Spring Boot采取了一个不同的方式,允许你真正的嵌套jar文件。

想要创建一个可执行jar文件,我们需要在pom.xml中添加spring-boot-maven-plugin,在dependencies段下面添加如下:

<build> 
    <plugins> 
        <plugin> 
            <groupId>org.springframework.boot</groupId> 
            <artifactId>spring-boot-maven-plugin</artifactId> 
        </plugin> 
    </plugins>
</build>

spring-boot-starter-parent的POM包含<executions>配置,绑定了repackage goal,如果你没有使用parent POM,你需要自己声明这个配置,参考插件文档

保存你的pom.xml并且在命令行中运行mvn package

$ mvn package

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] .... ..
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myproject ---
[INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.3.6.RELEASE:repackage (default) @ myproject ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

这时你在target目录中就能看到myproject-0.0.1-SNAPSHOT.jar,这个文件的大小应该在10Mb左右。如果你想查看文件内部的情况,可以使用jar tvf

$ jar tvf target/myproject-0.0.1-SNAPSHOT.jar

target目录中应该还可以看到一个小得多的文件,名为myproject-0.0.1-SNAPSHOT.jar.original,这是在Spring Boot执行repackag之前Maven创建的原始jar文件。

要运行应用,我们可以使用java -jar命令:

$ java -jar target/myproject-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\
( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\
 \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot :: (v1.3.6.RELEASE)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.536 seconds (JVM running for 2.864)

和之前一样,如果想退出应用,按ctrl-c

接下来阅读什么内容

希望这个章节给你提供了一些Spring Boot的基础,并且能帮助你创建好自己的应用,打开新世界的大门。如果你是一个任务导向型的开发者,你可能想跳转到spring.io并且查看getting started指南获取特定Spring功能使用问题的解决方案。我们也有Spring Boot的How-to文档可以参考。

Spring Boot repository中也有一些样例可以运行。所有的样例都是和余下的代码相独立的,你不需要编译其他的代码。

另外,逻辑上接下来应该阅读的内容是“使用Spring Boot”,但如果你实在是缺乏耐心,你也可以直接跳到Spring Boot features
.

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

推荐阅读更多精彩内容