《Spring Boot实战》读书笔记

2017-04-14

第1章 入门

目标

  • Spring Boot提供了一种新的编程范式,能在最小的阻力下开发Spring程序。专注于应用程序功能,不用在Spring配置上多花功夫。
    • Spring2.5有基于注解的组件扫描;Spring3.0引入了基于Java的配置(一种类型安全的可重构配置方式,可代替XML)。
    • 组件扫描减少了配置量,Java配置让它看上去简洁不少,但Spring还是需要不少配置。
    • 但依然还需要很多配置:
      • 如事务管理和SpringMVC,还是需要XML或Java显式配置;
      • 配置Servlet和过滤器(如Spring的DispatcherServlet)同样需在web.xml或Servlet初始化代码里进行显式配置。

优势

  • 快速开发能力
    • Spring Boot的目标是使用更少的代码,更快地写出好的生产系统。
  • 强大运维能力
    • Spring Boot在运维方面做了很多工作,部署、监控、度量,结合Spring Cloud还可轻松实现服务发现、服务降级。

springboot特性

  • 自动配置:spring常见的应用功能,自动提供相关配置
    • 数据库、Java持久化API、Thymeleaf模板、安全、springMVC等,不用再写Java或XML配置
  • 起步依赖:只需告诉springboot需要什么功能,就能引入需要的库且无版本冲突。
    • spring-core、spring-web、spring-webmvc、jackson-databind、hibernate-validator等。
  • Actuator:了解运行中的springboot程序。可通过Shell、web端点提供信息。
    • Spring应用程序上下文里配置的Bean
    • SpringBoot的自动配置做的决策
    • 应用程序取到的环境变量、系统属性、配置属性和命令行参数
    • 应用程序里线程的当前状态
    • 应用程序最近处理过的http请求的追踪情况
    • 各种和内存用户、垃圾回收、web请求以及数据源用量相关的指标
  • 命令行界面(不常用):SpringBoot Cli

与spring的关系

  • 就是spring,只不过省略了在使用spring时始终需要去做的Spring Bean配置。

第2章 开发springboot项目

初始化方式

  • [web方式](http://start.spring.io)
  • Intellij IDEA
  • Spring tool suite
  • Spring Boot CLI

文件结构

+ src
    + main
        + java
            + com.example
                - DemoApplication.java
        + resources
            - application.properties
            + static
            + templates
    + test
        + java
            + com.example
                - DemoApplicationTests.java
- pom.xml
  • DemoApplication.java
    • 程序起动引导类
    • @SpringBootApplication 开启组件扫描自动配置功能。相当于spring中的@Configuration、@ComponentScan、@EnableAutoConfiguration之和。
    • main方法中调用SpringApplication.run来启动引导应用程序
  • application.properties 配置信息
    • server.port=8080
  • 构建
    • mvn spring-boot:run

使用起步依赖

  • 起步依赖本质上是一个maven项目对象模型(POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。
  • 不需要指定版本号:起步依赖版本由spring boot的版本决定;起步依赖决定它们引入的传递依赖的版本。
  • 可以显示指定版本进行覆盖。

使用自动配置

  • spring boot的自动配置是一个运行时(准确地说,是应用程序启动时)的过程。
  • 一般代码结构

    + @Entity
        - @Id、@GeneratedValue(strategy=GenerationType.AUTO)
    + JpaRepository
    + service
    + controller
    
  • 自动配置的实现:使用了spring的条件化配置Contition
    • 自定义Contition类public class JdbcTemplateCondition implements Condition
    • 在Bean上加注解:@Conditional(JdbcTemplateCondition.class),则只有满足条件,此Bean才会创建

第3章 自定义配置

覆盖Spring Boot自动配置

  • 大多数情况下,自动配置的Bean可满足需要。但有时需显示配置来覆盖自动配置。
安全配置:保护应用程序
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  • 添加如上依赖后,会使用HTTP基础身份验证,但不友好。
    • 用户名:user
    • 密码在启动时,日志中打出:Using default security password: c70e829a-b9ae-4ccb-90b3-c904c7e3b2d4
创建自定义的安全配置
  • 当自动配置不存在,直接显式写配置。spring支持的xml形式即可,但Java形式的配置更优雅一些。

    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter
    
掀开自动配置的神秘面纱
  • spring boot的设计是加载应用级配置,随后再考虑自动配置类。

    @Configuration
    @EnableConfigurationProperties
    @ConditionalOnClass({ EnableWebSecurity.class })         @ConditionalOnMissingBean(WebSecurityConfiguration.class)         @ConditionalOnWebApplication
    public class SpringBootWebSecurityConfiguration 
    

通过属性文件外置配置

  • 微调细节,放弃自动配置不合算。直接通过外置配置来修改
    • application.properties
    • java -jar XXX.jar –server.port=18000
    • 通过@PropertySource标注的属性源
自动配置微调
  • 禁用模板缓存
    • 开发过程中禁用thymeleaf模板缓存:spring.thymeleaf.cache=false
  • 配置嵌入式服务器
    • server.port=18000
    • 启用ssl
      • 使用JDK的keytool工具创建keystore:keytool -keystore mykeys.jks -genkey -alias tomcat -keyalg RSA
      • server.ssl.key-store=file:///path/mykeys.jks
      • server.ssl.key-store-password=XXX
      • server.ssl.key-password=XXX
  • 配置日志
    • 默认使用logback,info级别
    • 自定义日志配置:在classpath根目录(src/main/resources)创建logback.xml
    • 也可以在不创建logback.xml文件情况下通过修改application.properties实现
  • 配置数据源
    • application.properties无需指定驱动,spring boot会根据数据库URL自动实别。
应用程序Bean的配置外置
@Component
@ConfigurationProperties("amazon")
public class AmazonProperties {
    private String associateId;
}
  • ConfigurationProperties注解表明此Bean从配置属性值注入前缀为amazon的属性
  • application.properties中增加amazon.associateId=XXX,那么此Bean即可获取到
  • spring boot的属性解析器,将associateId、associate_id、associate-id视为相同
使用Profile进行配置
  • 应用程序布署到多个环境(dev、qa、stage、product),配置细节可能不同。Spring的Profile配置是条件化配置,基于运行时激活Profile使用不同的Bean或配置类。
  • 如下需在运行时激活production Profile才能使用此配置

    @Profile("production")
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    }
    
  • 设置spring.profiles.active=production也可激活
  • 若使用application.properties,可创建application-{profile}.properties格式的文件,即可提供特定于profile的属性

定制应用程序错误页面

  • Spring Boot自动配置的默认错误处理器会查找名为error的视图(页面),如不存在则使用默认错误页Whitelabel Error Page
  • 如使用Thymeleaf,则需error.html,不需要单独写path为error的rest接口。
  • error视图可获取的信息
    • timestamp:错误发生的时间
    • status:HTTP状态码
    • error:错误原因
    • exception:异常的类名
    • message:异常消息(如果这个错误是由异常引起的)
    • errors:BindingResult异常里的各种错误(如果这个错误是由异常引起的)
    • trace:异常跟踪信息(如果这个错误是由异常引起的)
    • path:错误发生时请求的URL路径
  • demo

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/>
        <title>这是一个错误页面</title>
        <link rel="stylesheet" type="text/css" th:href="@{/css/index.css}" />
    </head>
    <body>
        <p>错误发生时间:<span th:text="${timestamp}"></span></p>
        <p>http状态:<span th:text="${status}"></span></p>
        <p>错误原因:<span th:text="${error}"></span></p>
        <p>异常类:<span th:text="${exception}"></span></p>
        <p>请求路径:<span th:text="${path}"></span></p>
        <p th:text="${'错误详情: ' + message}"></p>
        <p>BindingResult异常里的各种错误:<span th:text="${errors}"></span></p>
        <p>异常跟踪信息:<span th:text="${trace}"></span></p>
    
    <div class="copyright">
        <p>
            <a href="http://www.mamian.net/">www.mamian.net</a>
            <a href="http://www.miibeian.gov.cn/" target="_blank" style="margin-left:10px">京ICP备15014219号</a>
        </p>
    </div>
    <div class="copyright">
        <p>
            © 2016&nbsp;&nbsp;马面&nbsp;&nbsp;All Rights Reserved
        </p>
    </div>
</body>
</html>

第4章 测试


第5章 Groovy与Spring Boot Cli


第6章 Spring Boot+Grails


第7章 Actuator

  • 作用:暴露自身信息,提供系统监控数据
  • 使用方式
    • rest端点(最常用)
    • 远程shell
    • JMX

Actuator端点

  • Actuator提供众多Web端点,用以了解应用程序内部状态。
    • 应用配置类:获取应用程序中加载的应用配置、环境变量、自动化配置报告等与Spring Boot应用密切相关的配置类信息。
    • 度量指标类:获取应用程序运行过程中用于监控的度量指标,比如:内存信息、线程池信息、HTTP请求统计等。
    • 操作控制类:提供了对应用的关闭等操作类功能。
HTTP方法 路径 描述
GET /autoconfig 提供自动配置报告,记录哪些自动配置条件通过了,哪些没通过
GET /configprops 描述配置属性(包含默认值)如何注入Bean
GET /beans 描述应用程序上下文里全部的Bean,以及它们的关系
GET /dump 获取线程活动的快照
GET /env 获取全部环境属性
GET /env/{name} 根据名称获取特定的环境属性值
GET /health 报告应用程序的健康指标,这些值由HealthIndicator的实现类提供
GET /info 获取应用程序的定制信息,这些信息由info打头的属性提供
GET /mappings 描述全部的URI路径,以及它们和控制器(包含Actuator端点)的映射关系
GET /metrics 报告各种应用程序度量信息,比如内存用量和HTTP请求计数
GET /metrics/{name} 报告指定名称的应用程序度量值
POST /shutdown 关闭应用程序,要求endpoints.shutdown.enabled设置为true
GET /trace 提供基本的HTTP请求跟踪信息(时间戳、HTTP头等)
  • 引用方式

    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
查看配置明细
  • 获得Bean装配报告(/beans)
    • spring应用程序上下文中有哪些bean,每个bean的resource、dependencies、scope、type、name
  • 详解自动配置(/autoconfig)
    • 为什么会有某个Bean或为什么没有。
  • 查看配置属性(/env)
    • 所有环境属性列表:环境变量、JVM属性、命令行参数、applicaition.properties属性
    • 出于安全性,所有名为password、secret、key(或名字中最后一段是这些),返回“*”
  • 生成端点到控制器的映射(/mappings)
运行时度量
  • 查看应用程序的度量值(/metrics)
分类 前缀 报告内容
垃圾收集器 gc.* 已经发生过的垃圾收集次数,以及垃圾收集所耗时间,适用于标记-清理、并行收集器
内存 mem.* 分配给应用程序的内存数量和空闲内存数量(数据来自java.lang.Runtime)
heap.* 当前内存用量(数据来自java.lang.management.MemoryUsage)
类加载器 classes.* JVM类加载器加载与缷载的类数量(数据来自java.lang.management.ClassLoadingMXBean)
系统 processors uptime instance.uptime systemload.average 系统信息:处理器数(java.lang.Runtime)、运行时间(java.lang.management.RuntimeMXBean)、平均负载(java.lang.management.OperationSystemMXBean)
线程池 threads.* 线程、守护线程数,jvm启动后线程数峰值(java.lang.management.ThreadMXBean)
数据源 datasource.* 数据源连接的数量(源自数据源的元数据,仅当spring应用程序上下文里存在DataSource Bean时才会有这个信息)
tomcat会话 httpsessions.* tomcat活跃会话数和最大会话数(数据源自嵌入式tomcat的bean,仅在使用嵌入式tomcat时才有此信息)
HTTP counter.status. gauge.response. 多种应用程序服务http请求的度量值与计数器
  • 追踪Web请求(/trace)

    • web请求的方法、路径、时间戮、请求响应头信息
  • 导出线程活动(/dump)

    • 当前线程活动的快照
  • 监控应用程序健康情况(/health)

关闭应用程序(/shutdown)
  • 微服务架构中,某个实例异常需关闭,则可直接post关闭
  • shutdown默认没有启动,通过endpoints.shutdown.enabled=true开启
获取应用信息(/info)
  • 在application.properties中设置info前缀的属性后,通过/info可获取到

连接Actuator的远程shell

  • 通过远程shell来查询Actuator端点信息

通过JMX监控应用程序

定制Actuator

  • 重命名端点
  • 启用和禁用端点
  • 自定义度量信息
  • 创建自定义仓库来存储跟踪数据
  • 插入自定义的健康指示器

保护Actuator端点

  • application.properties中增加management.context-path=/mgmt,则所有Actuator端点均增加/mgmt前缀
  • 使用Spring Security来保护/mgmt前缀的所有端点即可

第8章
部署SpringBoot应用程序

构建、运行方式

  • IDE(Spring ToolSuite、idea)
  • 命令行:代码目录下 mvn spring-boot:run
  • maven编译成jar,命令行运行
  • Spring Boot CLI
  • 编译成war,交给tomcat、jetty

布署到传统应用服务器(如tomcat)

  • 与传统web应用程序相反,将tomcat部署到了应用程序中。
  • 由于自动配置功能,springboot不需web.xml或Servlet初始化类来声明springMVC的DispatcherServlet。如直接编译为war,则无效,还要一个对Servlet初始化的东西。
    • jar修改为war
      • 此时war中没启用Spring MVC DispatcherServlet的web.xml或Servlet初始化类,war文件还不可用。需使用SpringBootServletInitializer
    • SpringBootServletInitializer
      • 作用1:配置Spring DispatcherServlet
      • 作用2:在Spring应用程序上下文里查找Filter、Servlet或ServletContextInitializer类型的Bean,把它们绑定到Servlet容器里。
      • 使用方法:创建类继承自SpringBootServletInitializer并覆盖其configure方法即可。
        • configure方法只注册了一个Application类,这就够了。没必要把其他的Spring配置类也注册进来,因为Application类上添加了@SpringBootApplication注解。这会隐性开启组件扫描,而组件扫描则会发现并应用其他配置类。
public class ReadingListServletInitializer extends SpringBootServletInitializer {
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }

}

附录A 开发者工具


org.springframework.boot
spring-boot-devtools

当用应程序以完整打包好的jar或war文件形式运行时,开发者工具会被禁用,所以没必要在构建生产包前移除依赖。

  • 作用
    • 自动重启:classpath里文件变化时重启应用
    • live reload:资源修改后自动刷新浏览器
    • 远程开发:远程部署时支持自动重启与live reload。
    • 默认的开发时属性值
  • 自动重启
    • 不会修改的类(如三方jar包)加载到基础类加载器,应用程序的代码加载到单独的重启类加载器中。检测到变更时,只有重启类加载器重启。
    • 不是所有classpath里资源变更后都会重启应用,如thymeleaf视图、static及public里静态资源。重启时会排除:/META-INF/resources、/resources、/static、/public、/templates。
    • 设置spring.devtools.restart.exclude来覆盖默认的重启排除目录
      spring:
      devtools:
          restart:
              exclude:/static/**,/templates/**
      
    • 关闭重启功能:
      spring:
      devtools:
          restart:
              enable:false
      
    • 仅修改某类文件时才重启:
      spring:
      devtools:
          restart:
              trigger-file:.trigger
      
  • live reload
    • 集成了LiveReload
    • 激活开发工具后,springboot启动内嵌的LiveReload服务器,在资源文件发生变化时触发浏览器刷新。但需在浏览器里安装LiveReload插件。
    • 禁用内嵌的LiveReload服务器
      spring:
      devtools:
          livereload:
              enable:false
      
  • 远程开发

    • 在远程dev环境上布署比较适合,可远程调试应用。支持自动重启、live reload。
    • 开启远程开发功能需设置远程安全码
      spring:
      devtools:
          remote:
              secret:mamian
      
    • 开启后,运行中的应用会启动一个服务器组件以监听接受变更的请求,可重启应用程序或触发浏览器刷新。
    • 需在本地运行远程开发工具的客户端(就是一个Java类org.springframework.boot.devtools.RemoteSpringApplication)。它会运行在IDE中,要求提供一个参数,告知远程应用部署在哪。
  • 默认的开发时属性

    • 有些属性仅在开发环境生效:如视图模板缓存在开发时需关掉以支持实时看到修改后的结果。
    • 当开发者工具激活后,以下属性会设置为false(如未开启开发者工具,默认为true)。这样就不需要在开发时使用Profile配置来禁用它们了。
      • spring.thymeleaf.cache
      • spring.freemarker.cache
      • spring.velocity.cache
      • spring.mustache.cache
      • spring.groovy.template.cache
  • 全局配置开发者工具
    • 同时开发多个项目,想使用相同的设置。
    • 在主目录(home directory)里创建.spring-boot-devtools.properties文件。如下内容
      • spring.devtools.restart.trigger-file=.trigger
      • spring.devtools.livereload.enabled=false
    • 每个项目中的application.properties或application.yml可覆盖这些属性。

Spring Boot起步依赖


配置属性

  • @ConfigurationProperties注解
  • 要指定内嵌tomcat或jetty监听端口,可设置server.port属性。此属性可设置于application.properties、application.yml、操作系统环境变量。
  • 设置的属性是否生效取决于对应的组件是否声明为spring应用程序上下文里的Bean(基本是自动配置的)。为一个不生效的组件设置属性是无效的。
  • wiki

Spring Boot依赖

  • 如起步依赖中未包含所需依赖,需显示依赖,不需指定版本号(如此依赖为springboot依赖管理范围内)。
  • wiki

Kommentare: