spring boot guide

当前Spring项目中的问题

  1. 大量的XML配置
  2. 配置很重复
  3. 配置很困难
  4. 配置难维护
  5. 复杂的依赖管理

Spring Boot 解决方案

  1. 约定大于配置(Convention over configuration)。
  2. 默认配置及不同优先级的可覆盖配置。

Spring Boot 目标和特性

  1. 快速创建独立部署的Spring应用程序。
  2. 使用嵌入式Tomcat,Jetty容器,无需部署WAR包,直接运行jar包。
  3. 简化Maven及Gradle配置。
  4. 尽可能的自动化配置Spring。
  5. 直接植入产品环境下的实用功能,比如度量指标、健康检查及扩展配置等。
  6. 无需代码生成及XML配置。

Spring Boot 项目结构示例

├─── src│    ├─── main│    │    ├─── java│    │    │    └─── com│    │    │         └─── example│    │    │              └─── myproject│    │    │                   ├─── Application.java│    │    │                   ││    │    │                   ├─── domain│    │    │                   │    ├─── Customer.java│    │    │                   │    └─── CustomerRepository.java│    │    │                   ││    │    │                   ├─── service│    │    │                   │    └─── CustomerService.java│    │    │                   ││    │    │                   └─── web│    │    │                        └─── CustomerController.java│    │    ├─── resources│    │    │    ├─── templates│    │    │    ││    │    │    ├─── static│    │    │    │    ├─── error│    │    │    │    │    ├─── 404.html│    │    │    │    │    └─── 500.html│    │    │    │    ││    │    │    │    └─── index.html│    │    │    ││    │    │    ├─── favicon.ico│    │    │    ├─── logback-spring.xml│    │    │    └─── application.properties│    │    ││    │    └─── webapp│    │         └─── WEB-INF│    │              └─── jsp│    │                   └─── index.jsp│    ││    └─── test│         ├─── java│         └─── resources└─── pom.xml

pom.xml

Spring Boot 项目创建可使用官方的工具:SPRING INITIALIZR

<?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>application-name</artifactId>    <version>0.0.1-SNAPSHOT</version>    <packaging>jar</packaging>    <name>${project.artifactId}</name>    <description>Demo project for Spring Boot</description>    <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>1.5.9.RELEASE</version>        <relativePath/>    </parent>    <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>        <java.version>1.8</java.version>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-test</artifactId>            <scope>test</scope>        </dependency>        <dependency>            <groupId>org.apache.tomcat.embed</groupId>            <artifactId>tomcat-embed-jasper</artifactId>        </dependency>    </dependencies>    <build>        <finalName>${project.artifactId}</finalName>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>            </plugin>        </plugins>    </build></project>

Spring Boot 应用示例

完整示例参考:https://spring.io/guides/gs/spring-boot/

@RestController@EnableAutoConfigurationpublic class Application {    @RequestMapping("/")    public String home() {        return "Hello World";    }    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

应用启动

 mvn spring-boot:run

jar包方式运行项目

利用Spring Boot maven插件生成可执行的fat jars,这种jar包含了工程的所有依赖并且能够以可运行jar的方式执行。建议是使用jar包方式运行项目,而不是使用war包方式。

如果你的应用被打包成jar,那就不要使用src/main/webapp文件夹。尽管该文件夹是通常web项目的标准配置方式,但它仅在打包成war的情况下起作用,在打包成jar时,多数构建工具都会默认忽略它。

 mvn package java -jar target/application-name.jar

项目配置文件

Spring Boot并不是用于生成代码的,它是用来启动项目的,使用它约定的默认配置,可以在属性文件或者项目启动命令行参数中重写这些属性。默认情况下,应用的配置文件名为application.properties,并且位于应用的classpath根目录下,也可以使用YAML方式配置,它提供了结构化以及嵌套的配置。

配置文件默认文件名和位置

  1. src/main/resources/application.yml
  2. src/main/resources/application.properties

YAML缺点

YAML文件不能通过@PropertySource注解加载,如果需要使用该方式,那就必须使用properties文件。

application.yml 示例

spring:  mvc:    view:      prefix: /WEB-INF/jsp/      suffix: .jsp  application:    name: application-name  datasource:    driverClassName: com.mysql.jdbc.Driver    url: jdbc:mysql://localhost:3306/jdbc?useUnicode=true&useSSL=true    username: dbuser    password: dbpasslogging:  level:    root: WARN  com:    example: INFO

配置参数设置级别

Spring Boot所提供的配置方式有15种以上,主要配置方式优先级顺序如下所示。

  1. 命令行参数。
  2. 来自 SPRING_APPLICATION_JSON 的属性(环境变量或系统属性中内嵌的内联JSON)。
  3. 通过System.getProperties()获取的Java系统参数。
  4. 操作系统环境变量。
  5. 应用Jar文件内的属性文件。
  6. 应用Jar文件外的属性文件。
  7. 通过SpringApplication.setDefaultProperties声明的默认属性。

比如可以使用应用启动时Java的命令行参数重置它的默认配置。

 java -Dserver.port=8888 -Dspring.profiles.active=prod -jar target/application-name.jar

静态资源和首页配置

  1. 静态资源默认放在src/main/resources文件夹的/static下面。
  2. 静态主页默认放在resources/static/下放入一个index.html即可。
  3. favicon.ico可放在resources文件夹下。

视图模板

默认支持的视图

Spring Boot会对thymeleaf、freemarker、groovy和mustache四种模板进行自动配置,默认的模板路径为:resources/templates

jsp视图配置

如果使用JSP作为模板时需要额外进行一点配置,首先在appliation.properties中添加以下2个配置,并且pom.xml要包括jsp compiler的依赖。

spring.mvc.view.prefix=/WEB-INF/jsp/spring.mvc.view.suffix=.jsp

jsp编译依赖

缺少这个依赖,会抛出如下异常:

Did not find handler method for [/WEB-INF/jsp/index.jsp]

<dependency>    <groupId>org.apache.tomcat.embed</groupId>    <artifactId>tomcat-embed-jasper</artifactId></dependency>

自定义错误页路径

src/main/resources/static/error/404.html

数据库连接池自动配置

  1. 优先查找HikariCP连接池
  2. 然后查找tomcat-jdbc连接池
  3. 最后查找dbcp2连接池

关于 Spring Boot 的自动配置

  1. Spring Boot的自动配置,是通过Starters和Conditional Annotations实现的。
  2. 自动配置基于类路径中的JAR和定义Bean的方式。
  3. Starter实际上是一组依赖项,Spring Boot会根据应用中声明的第三方依赖来自动配置Spring框架,
    而不需要进行显式的声明。
  4. 在项目中可以自由地配置Starters以外的jar依赖,
    Spring Boot仍会尽最大努力去自动配置你的应用。
  5. Spring Boot的自动配置功能是没有侵入性的,只是作为一种基本的默认实现。
    开发人员可以通过定义其他Bean来替代自动配置所提供的功能。
  6. Spring Boot推荐采用基于Java注解的配置方式,而不是传统的XML。
  7. 查看Spring Boot启动时通过--debug查看AUTO-CONFIGURATION REPORT
     java -jar target/application-name.jar --debug
  8. 排除自动装配,比如pom中有导入jdbc相关包的依赖,但需要排除数据库自动装配。
    @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

常用到的部分Starters

  1. spring-boot-starter
  2. spring-boot-starter-web
  3. spring-boot-starter-amqp
  4. spring-boot-starter-data-jpa
  5. spring-boot-starter-data-mongodb
  6. spring-boot-starter-data-redis
  7. spring-boot-starter-jdbc
  8. spring-boot-starter-mail
  9. spring-boot-starter-security
  10. spring-boot-starter-test
  11. spring-boot-starter-thymeleaf
  12. spring-boot-starter-validation
  13. spring-boot-starter-tomcat
  14. spring-boot-starter-jetty
  15. spring-boot-starter-logging
  16. spring-boot-starter-cache

底层实现默认配置使用的注解

  1. @ConditionalOnClass and @ConditionalOnMissingClass
  2. @ConditionalOnBean and @ConditionalOnMissingBean
  3. @ConditionalOnWebApplication and @ConditionalOnNotWebApplication
  4. @ConditionalOnProperty
  5. @ConditionalOnResource
  6. @ConditionalOnExpression

注解使用源码Example1

Spring Boot源码中关于spring webmvc相关的自动配置,摘录部分代码示例如下:

@Configuration@ConditionalOnWebApplication@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class })@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration {    @Bean    @ConditionalOnMissingBean(HiddenHttpMethodFilter.class)    public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {        return new OrderedHiddenHttpMethodFilter();    }    @Bean    @ConditionalOnMissingBean(HttpPutFormContentFilter.class)    @ConditionalOnProperty(prefix = "spring.mvc.formcontent.putfilter", name = "enabled", matchIfMissing = true)    public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {        return new OrderedHttpPutFormContentFilter();    }    @Configuration    @Import(EnableWebMvcConfiguration.class)    @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })    public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {        @Bean        @ConditionalOnMissingBean        public InternalResourceViewResolver defaultViewResolver() {            InternalResourceViewResolver resolver = new InternalResourceViewResolver();            resolver.setPrefix(this.mvcProperties.getView().getPrefix());            resolver.setSuffix(this.mvcProperties.getView().getSuffix());            return resolver;        }    }}

注解使用源码Example2

@Configuration@ConditionalOnClass(Gson.class)public class GsonAutoConfiguration {    @Bean    @ConditionalOnMissingBean    public Gson gson() {        return new Gson();    }}

Spring Framework 和 Spring Boot 的形象比较

Spring Framework是建立一个应用的各个组件部分,完成一个应用需要开发人员组装配置很多内容,一般是通过XML配置各种Bean以及Bean的依赖关系。
Spring Boot则是把应用启动所需要的默认配置都已经组装配置好了,开发人员只要在上面加入自己的业务逻辑就可以使应用快速运行起来。如果有组件要替换,只要改变项目的依赖即可。

Spring Framework

Spring Boot

References

  1. Spring Boot Reference Guide
  2. Building an Application with Spring Boot
  3. SPRING INITIALIZR bootstrap your application now
  4. Spring Boot Starters list
  5. 深入学习微框架:Spring Boot
  6. 使用 Spring Boot 快速构建 Spring 框架应用
  7. Spring Boot参考指南