使用SpringBoot快速构建应用
Spring Boot于2014年4月发布1.0.0版本, 用于创建Spring 4.0项目, 简化了Spring中繁琐的配置, 提高了开发效率
Spring Boot简介
- Spring Boot致力于快速构建应用, 去掉了- Spring的繁琐配置, 使创建Spring应用就像写一个- main函数一样方便.
- 直接嵌入Tomcat或Jetty服务器, 不需要部署 WAR 文件, 可以直接run
- 无XML配置(也支持导入XML配置)
- 构建Spring4应用, 最好使用高版本环境(JDK8,Maven3.2+,Servlet3.0+)
- 提供了maven插件, 可把应用及所需要的所有依赖包内嵌到一个jar包中
- 提供了一个命令行工具Spring Boot CLI(安装方法)
- 支持Groovy编程语言
CLI和Groovy示例
Spring Boot CLI是一个命令行工具, 可以快速搭建Spring原型, 支持Groovy脚本.
 我们通过CLI使用Groovy脚本创建一个最简单的Web应用, 创建一个app.groovy文件, 内容如下:
@RestController
class ThisWillActuallyRun {
    @RequestMapping("/")
    String home() {
        "Hello World!"
    }
}然后在shell中运行下面命令:
$ spring run app.groovy则已经运行了一个Spring web应用(首次运行需要下载依赖包, 比较慢), 访问127.0.0.1:8080就会看到输出内容Hello World!
快速创建一个应用
通过Maven创建一个Spring Boot应用, 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.project</groupId>
    <artifactId>spring_boot</artifactId>
    <version>1.0</version>
    <!-- 继承spring-boot-starter-parent是最快的方式, 后面有不继承该怎么写 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.1.RELEASE</version>
    </parent>
    <!-- 这一个依赖就够了 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>可以通过mvn dependency:tree来看看都用到了哪些jar包
从src/main/java/目录下创建一个类src/main/java/Example.java:
@RestController
@EnableAutoConfiguration
public class Example {
    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }
    public static void main(String[] args) throws Exception {
        SpringApplication.run(Example.class, args);
    }
}到此整个应用就创建完毕, 可以直接运行main方法启动容器, 访问127.0.0.1:8080
运行容器的方式
- 像上面那样直接运行main方法
- 通过mvn spring-boot:run命令运行
- 创建可执行jar包运行
通过插件spring-boot-maven-plugin可将应用及依赖打成jar包, 如果没有继承spring-boot-starter-parent则需要主动添加一下这个插件, 并且parent中的<executions>需要自己进行配置
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
        </plugin>
    </plugins>
</build>通过命令mvn package打包, 将会得到target/spring_boot-1.0.jar文件, 可通过命令jar tvf target/myproject-1.0.jar查看该jar包的结构. 除此之外, 还有个文件target/spring_boot-1.0.jar.original, 这是Spring Boot重新打包之前, Maven创建的原始jar文件
使用命令java -jar target/spring_boot-1.0.jar即可运行
依赖管理
上面都是以继承spring-boot-starter-parent的形式进行一来管理, 这个parent里有如下内容:
- 指定了Java的版本, 和编码(不继承parent可自己指定)
- <resource.delimiter>配置, 除了接受原有的Spring形式的${…}, 还支持了Maven的@..@形式(不继承parent可自己指定)
- 包依赖管理, 继承自spring-boot-dependencies(不继承parent的形式就是引入这个pom)
- 插件配置(不继承parent需要自己配置)
因此, 如果不继承spring-boot-starter-parent, 我们的pom文件可以这么写:
    <properties>
        <java.version>1.8</java.version>
        <resource.delimiter>@</resource.delimiter> <!-- delimiter that doesn't clash with Spring ${} placeholders -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <tomcat.version>7.0.57</tomcat.version> <!-- 配置你的tomcat版本 -->
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>1.4.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <!-- 如果是通过parent方式继承spring-boot-starter-parent则不用配置此插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>目录结构及配置
官方建议项目有一个标准的目录结构, 就像其他Spring项目一样, 包名采用一个反转的域名, 结构类似于下面这样:
com.example.myproject
         +- Application.java
         |
         +- service
         |   +- CustomerService.java
         |
         +- controller
             +- CustomerController.java其中Application.java的内容如下:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}该项目中Application.java为main类, 将main类放到其他类所在包的顶层(root package), 并将@EnableAutoConfiguration注解加main类上, 这样就隐式地定义了一个基础包扫描路径, 所以采用root package时, @ComponentScan注解就不需要添加basePackage属性了
解释下这几个注解的意思:
- @Configuration: 表示一个配置类, 类似于原来的一个- xml文件
- @EnableAutoConfiguration: Spring Boot的自动配置会根据所添加的jar包依赖自动配置Spring应用, 通常项目中只有一个- @EnableAutoConfiguration注解, 并建议将它加到主配置类(- primary @Configuration)上
- @ComponentScan: 包扫描路径, 采用- root package形式会自动收集- root package包下所有组件, 包括配置类(- @Configuration类)
由于平时配置main类时, 频繁的一起使用@Configuration、@EnableAutoConfiguration、@ComponentScan这三个注解, 因此Spring Boot提供了一个简单的注解SpringBootApplication来代替这三个注解, 其效果与这三个注解一起使用的效果完全一样
另外, 还有几个有用的用法:
- @Import: 导入其他配置类
- @ImportResource: 引入- XML形式的配置
- @EnableAutoConfiguration(exclude={XXXConfiguration.class})排除某些配置, 若配置类不在- classpath中, 可以使用- excludeName属性指定全限定名
