Spring Boot 官网文档简单翻译 Part IX

Part IX. ‘How-to’ guides

文档说明:

  • 文档对应的版本为 2.1.0.M3
  • 这不是文档的完整中文翻译,也有可能跟原文文字不一一对应,只是我阅读文档时候做的简单笔记
  • 如果对应的章节没有任何中文,有可能是文档内容比较少,建议直接看原文,或者是我不感兴趣的部分
  • 目录标题没有做翻译,首先标题一般一眼就能看懂什么意思,不做翻译还能保证原文意思,其次也方便对应到原文位置

这个篇章主要是对在使用 Spring Boot 的过程中经常出现的问题提供的一份指引。
如果你想完善这份指引,欢迎你给我们提一个 PR。

75. Spring Boot Application

75.1 Create Your Own FailureAnalyzer

FailureAnalyzer 可以把在启动服务过程中的出现异常解析成人类可读的信息
AbstractFailureAnalyzer 提供了很多默认实现。如果你处理不了出现的异常,就返回 null,给其他的 FailureAnalyzer 接口实现机会去解析这个异常。

FailureAnalyzer 必须在 META-INF/spring.factories 配置文件里面注册,例如:

org.springframework.boot.diagnostics.FailureAnalyzer=com.example.ProjectConstraintViolationFailureAnalyzer

75.2 Troubleshoot Auto-configuration

Spring Boot 的自动装配会尽力做正确的事情,但是有些时候你发现有些问题很难找到原因,Spring Boot 也没有判断出明确的问题。

ApplicationContext 的 ConditionEvaluationReport 或者 spring-boot-actuator 的 conditions endpoint

很多问题通过阅读源代码和 Javadoc 能够解决,有一些经验可以看下:

  • 检查 AutoConfiguration 类的代码,特别留意 @Conditional 的注解,找出什么时候加了什么功能。启动服务的时候在命令行加上 --debug 或者在系统环境变量加上 -Ddebug,在控制台输出获取 auto-configuration 的各项决策。如果启用了 spring-boot-actuator,获取 conditions endpoint 的信息。

  • 检查 @ConfigurationProperties 修饰的类,校验里面的配置选项。@ConfigurationProperties 有个 name 属性会作为属性名称的前缀,例如 ServerProperties 里面配置的前缀是 server,配置项有可能是 server.port 等等。如果启用了 spring-boot-actuator,获取 configprops endpoint 的信息。

  • 检查 Binder 的 bind() 方法从 Environment 拉取的配置列表值。

  • 检查直接绑定到 Environment 的 @Value 注解

  • 检查可以通过 SpEL 控制是否启用某些特性的 @ConditionalOnExpression 注解

75.3 Customize the Environment or ApplicationContext Before It Starts

一个 SpringApplication 有 ApplicationListeners 和 ApplicationContextInitializers 来定制化 context 和 environment。Spring Boot 从 META-INF/spring.factories 加载了很多定制化功能。

  • 编码显示配置,在 SpringApplication 启动前调用 addListeners 和 addInitializers 方法
  • 配置文件里面设置 context.listener.classes 和 context.initializer.classes 属性
  • 添加属性到 META-INF/spring.factories,并打包成 jar 文件让其他应用都引用这个 jar 文件

注册完监听器后,SpringApplication 会触发很多事件给监听器。

实现 EnvironmentPostProcessor 接口可以定制化 Environment 的信息,需在 META-INF/
spring.factories 添加相应配置:

org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

这个实现可以加载任意数量的文件并添加到 Environment,下面给出一个接口实现的例子:

public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {
    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
    
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Resource path = new ClassPathResource("com/example/myapp/config.yml");
        PropertySource propertySource = loadYaml(path);
        environment.getPropertySources().addLast(propertySource);
    }
    
    private PropertySource loadYaml(Resource path) {
        if (!path.exists()) {
            throw new IllegalArgumentException("Resource " + path + " does not exist");
        }
        try {
            return this.loader.load("custom-resource", path).get(0);
        }
        catch (IOException ex) {
            throw new IllegalStateException(
            "Failed to load yaml configuration from " + path, ex);
        }
    }
}

Caution: 不建议使用 @PropertySource 从 Environment 加载自定义配置的资源文件,因为这个注解的加载时机很晚。

75.4 Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)

ApplicationBuilder
章节 23.4 Fluent Builder API

75.5 Create a Non-web Application

setWebApplicationType(WebApplicationType.NONE)

76. Properties and Configuration

主要讲解配置的读和写,还有它们和 Spring Boot 应用的交互

76.1 Automatically Expand Properties at Build Time

通过占位符来让配置内容根据运行时的情况来配置

76.1.1 Automatic Property Expansion Using Maven

Maven + spring-boot-starter-parent
使用 @..@ 占位符

[email protected]@
[email protected]@

76.1.2 Automatic Property Expansion Using Gradle

app.name=${name}
app.description=${description}

Note: Gradle 的占位符 {..}

76.2 Externalize the Configuration of SpringApplication

配置项 spring.main.* 可以指定 SpringApplication 的属性

spring.main.web-application-type=none
spring.main.banner-mode=off

配置文件的内容会覆盖代码里面的配置

new SpringApplicationBuilder()
    .bannerMode(Banner.Mode.OFF)
    .sources(demo.MyApp.class)
    .run(args);

76.3 Change the Location of External Properties of an Application

各个位置的配置内容会按顺序加载到 Environment,改变了配置的位置某种角度上会改变加载配置文件的优先级。

76.4 Use 'Short' Command Line Arguments

如何达到用 --port=9000 实现 --server.port=9000 的效果,通过占位符来起一个别名

server.port=${port:8080}

76.5 Use YAML for External Properties

YAML 是 JSON 的超集,解析文件的时候会映射成键值对。

76.6 Set the Active Spring Profiles

命令行

$ java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar

application.properties

spring.profiles.active=production

76.7 Change Configuration Depending on the Environment

通过 Profile 的机制来实现,各个 Profile 的内容会写在同一个 YAML 文件。

76.8 Discover Built-in Options for External Properties

配置项的列表参看文档后面的附录

77. Embedded Web Servers

嵌入式的服务器问题主要有两个方面:如何更换和如何配置

77.1 Use Another Web Server

给一个在 Maven 去除 tomcat 自动配置的例子


    3.1.0



    org.springframework.boot
    spring-boot-starter-web
    
        
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    




    org.springframework.boot
    spring-boot-starter-jetty

77.2 Disabling the Web Server

application.properties

spring.main.web-application-type=none

77.3 Change the HTTP Port

application.properties

server.port=9000

77.4 Use a Random Unassigned HTTP Port

application.properties

server.port=0

77.5 Discover the HTTP Port at Runtime

通过应用的启动日志可知道占用的端口,如果是以随机端口模式启动的服务,在程序里面怎么获取其端口号呢

  • ServletWebServerApplicationContext
  • @LocalServerPort

77.6 Enable HTTP Response Compression

响应内容默认大于 2048 字节才会启用压缩功能

server.compression.enabled=true
server.compression.min-response-size=2048
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml

77.7 Configure SSL

配置项:server.ssl.*

77.8 Configure HTTP/2

配置项:server.http2.enabled

77.9 Configure the Web Server

77.10 Add a Servlet, Filter, or Listener to an Application

Add a Servlet, Filter, or Listener by Using a Spring Bean

@Bean

Add Servlets, Filters, and Listeners by Using Classpath Scanning

@WebServlet, @WebFilter, and @WebListener

77.11 Configure Access Logging

配置访问日志,以 Jetty 为例:

server.jetty.accesslog.enabled=true
server.jetty.accesslog.filename=/var/log/jetty-access.log

更多内容可参看其官网文档

77.12 Running Behind a Front-end Proxy Server

application.properties

server.use-forwardheaders=true

77.13 Enable Multiple Connectors with Tomcat

77.14 Use Tomcat’s LegacyCookieProcessor

77.15 Enable Multiple Listeners with Undertow

77.16 Create WebSocket Endpoints Using @ServerEndpoint

想在要嵌入式的容器使用 @ServerEndpoint,需声明一个 ServerEndpointExporter bean

@Bean
public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
}

78. Spring MVC

78.1 Write a JSON REST Service

依赖了 Jackson2 库,@RestController 的响应默认是 JSON

@RestController
public class MyController {
    @RequestMapping("/thing")
    public MyThing thing() {
        return new MyThing();
    }
}

78.2 Write an XML REST Service

添加 jsckson-dataformat-xml 依赖


    com.fasterxml.jackson.dataformat
    jackson-dataformat-xml

代码示例:

@XmlRootElement
public class MyThing {
    private String name;
    // .. getters and setters
}

78.3 Customize the Jackson ObjectMapper

Jackson2ObjectMapperBuilder
ObjectMapper or XmlMapper

78.4 Customize the @ResponseBody Rendering

HttpMessageConverters

78.5 Handling Multipart File Uploads

Spring Boot 支持 Servlet 3 javax.servlet.http.Part API。
参看 MultipartProperties 类。
更多详情请参看 MultipartAutoConfiguration 类。

78.6 Switch Off the Spring MVC DispatcherServlet

78.7 Switch off the Default MVC Configuration

提供一个 @Configuration 和 @EnableWebMvc 修饰的类。

78.8 Customize ViewResolvers

ViewResolver 是 Spring MVC 的核心组件,把 @Controller 的视图名称转换成实际的视图实现。
WebMvcAutoConfiguration 添加了一些 ViewResolver 到你的 context

79. Testing With Spring Security

可以配置指定用户来运行测试用例

@Test
@WithMockUser(roles="ADMIN")
public void requestProtectedUrlWithUser() throws Exception {
    mvc.perform(get("/"))
    ...
}

80. Jersey

80.1 Secure Jersey endpoints with Spring Security

在 Jersey 使用 Spring Security 方法级别的安全机制。

81. HTTP Clients

81.1 Configure RestTemplate to Use a Proxy

你可以用 RestTemplateCustomizer 和 RestTemplateBuilder 来生成一个自定义的 RestTemplate,这也是将 RestTemplate 用作代理的推荐生成方法。

82. Logging

Spring Boot 会有优先选择 Logback 库来写日志,开发者要做的一般是定义各类日志的级别就可以了。

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

82.1 Configure Logback for Logging

logback.xml 或者 logback-spring.xml,再或者就是配置路径



    
    

spring-boot.jar 文件里面有 base.xml,里面有些环境变量的占位符

  • ${PID}
  • ${LOG_FILE}
  • ${LOG_PATH}
  • ${LOG_EXCEPTION_CONVERSION_WORD}

Configure Logback for File-only Output

日志只输出到文件,需要配置 logback-spring.xml

82.2 Configure Log4j for Logging

添加依赖


    org.springframework.boot
    spring-boot-starter-web



    org.springframework.boot
    spring-boot-starter
    
        
            org.springframework.boot
            spring-boot-starter-logging
        
    



    org.springframework.boot
    spring-boot-starter-log4j2

Use YAML or JSON to Configure Log4j 2

默认使用 XML 格式的配置文件,也可以支持 YAML 和 JSON。
哪个方便用那个呗。

83. Data Access

83.1 Configure a Custom DataSource

通过定义 bean 的方式:

@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
    return new FancyDataSource();
}

app.datasource

app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30

配置 JNDI 的方式:

@Bean(destroyMethod="")
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
    return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS");
}

通过 DataSourceBuilder 类生成一个 DataSource

83.2 Configure Two DataSources

让其中一个 DataSource 成为 @Primary
当创建你自己的 DataSource,相关的自动装配逻辑会失效,可以自己把自动装配的工作做完:

@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSource firstDataSource() {
    return firstDataSourceProperties().initializeDataSourceBuilder().build();
}

@Bean
@ConfigurationProperties("app.datasource.second")
public BasicDataSource secondDataSource() {
    return DataSourceBuilder.create().type(BasicDataSource.class).build();
}

配置文件内容

app.datasource.first.type=com.zaxxer.hikari.HikariDataSource
app.datasource.first.maximum-pool-size=30

app.datasource.second.url=jdbc:mysql://localhost/test
app.datasource.second.username=dbuser
app.datasource.second.password=dbpass
app.datasource.second.max-total=30

83.3 Use Spring Data Repositories

Spring Data 创建了很多 @Repository 接口的实现,Spring Boot 会根据 @EnableAutoConfiguration 找到的配置内容来自动处理,很多时候你需要做的就是引入正确的依赖。

83.4 Separate @Entity Definitions from Spring Configuration

Spring Boot 会尝试找到 @Entity 类的位置,如需获取更多的控制,使用 @EntityScan 注解:

@Configuration
@EnableAutoConfiguration
@EntityScan(basePackageClasses=City.class)
public class Application {

    //...

}

83.5 Configure JPA Properties

配置项:spring.jpa.properties.*

83.6 Configure Hibernate Naming Strategy

83.7 Use a Custom EntityManagerFactory

83.8 Use Two EntityManagers

83.9 Use a Traditional persistence.xml File

83.10 Use Spring Data JPA and Mongo Repositories

83.11 Expose Spring Data Repositories as REST Endpoint

83.12 Configure a Component that is Used by JPA

83.13 Configure jOOQ with Two DataSources

84. Database Initialization

84.1 Initialize a Database Using JPA

  • spring.jpa.generate-ddl (boolean)
  • spring.jpa.hibernate.ddl-auto (enum)

84.2 Initialize a Database Using Hibernate

  • spring.jpa.hibernate.ddl-auto

84.3 Initialize a Database

可从 classpath 跟目录加载 schema-{platform}.sql 文件。

84.4 Initialize a Spring Batch Database

spring.batch.initialize-schema=always

84.5 Use a Higher-level Database Migration Tool

Execute Flyway Database Migrations on Startup

Flyway 是一款开源的数据库版本管理工具,Flyway 可以独立于应用实现管理并跟踪数据库的变更,Flyway 根据自己的约定,不需要复杂的配置就可以实现数据的迁移。

添加依赖:rg.flywaydb:flyway-core
迁移脚本的文件:V__.sql
脚本文件位置在 classpath:db/migration,可通过 spring.flyway.locations 配置项修改

spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration

Spring Boot 调用 Flyway.migrate() 来实现数据库迁移,可实现 FlywayMigrationStrategy 来获取更多的控制。
Flyway 支持基于 SQL 或者 Java 的回调。

Execute Liquibase Database Migrations on Startup

添加依赖:org.liquibase:liquibase-core

默认读取 db/changelog/db.changelog-master.yaml 文件

85. Messaging

85.1 Disable Transacted JMS Session

86. Batch Applications

Spring Batch 默认需要一个 DataSource 来存储 job details。

86.1 Execute Spring Batch Jobs on Startup

在应用启动的时候,默认会执行所有的 Job,可以通过 spring.batch.job.names 配置项来执行指定的 Job。

87. Actuator

87.1 Change the HTTP Port or Address of the Actuator Endpoints

端口默认和 HTTP 主服务一致。

management.server.port=8081
# a valid IP address to which the server is able to bind
management.server.address

87.2 Customize the ‘whitelabel’ Error Page

需要来处理 /error 路径的 View

87.3 Sanitize sensible values

通过 env endpoint 和 configprops endpoint 查看各项配置时,有些配置项是默认会屏蔽其内容的,例如 password。
控制这个的配置项支持正则表达式匹配:

management.endpoint.env.keys-to-sanitize
management.endpoint.configprops.keys-to-sanitize

88. Security

88.1 Switch off the Spring Boot Security Configuration

在应用里面定义 @Configuration 修饰的 WebSecurityConfigurerAdapter,便会关闭 Spring Boot 默认的应用安全策略。

88.2 Change the UserDetailsService and Add User Accounts

提供 AuthenticationManager, AuthenticationProvider, or UserDetailsService
最容易的方式是提供 UserDetailsService

88.3 Enable HTTPS When Running behind a Proxy Server

添加定制的 WebSecurityConfigurerAdapter:

@Configuration
public class SslWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // Customize the application security
        http.requiresChannel().anyRequest().requiresSecure();
    }
}

89. Hot Swapping

89.1 Reload Static Content

推荐做法是使用 spring-boot-devtools

89.2 Reload Templates without Restarting the Container

Thymeleaf Templates

# 参看 ThymeleafAutoConfiguration 了解更多的配置项
spring.thymeleaf.cache=false

FreeMarker Templates

# 参看 FreeMarkerAutoConfiguration 了解更多的配置项
spring.freemarker.cache=false

Groovy Templates

# 参看 GroovyAutoConfiguration 了解更多的配置项
spring.groovy.template.cache=false

89.3 Fast Application Restarts

spring-boot-devtools 模块的自动重启机制比冷启动快很多的。

89.4 Reload Java Classes without Restarting the Container

现在很多 IDE 工具都是支持替换字节码文件。

90. Build

90.1 Generate Build Information

Maven 和 Gradle 插件都允许生成构建信息,包含加载进来的名称和版本。

添加 build-info


    
        
            org.springframework.boot
            spring-boot-maven-plugin
            2.1.0.M3
            
                
                    
                        build-info
                    
                
            
        
    

90.2 Generate Git Information

Maven 和 Gradle 都可以在构建的时候生成一个包含你 git 源代码状态信息的 git.properties 文件。
添加如下配置:


    
        
            pl.project13.maven
            git-commit-id-plugin
        
    

90.3 Customize Dependency Versions

如需指定第三方库的版本号,可以添加对应的 元素,例如指定 slf4j 的版本号


    1.7.5

90.4 Create an Executable JAR with Maven

POM 有 spring-boot-starter-parent 的基础上,添加如下配置:


    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
    

POM 没有 spring-boot-starter-parent 的基础上,添加如下配置:


    
        
            org.springframework.boot
            spring-boot-maven-plugin
            2.1.0.M3
            
                
                    
                        repackage
                    
                
            
        
    

90.5 Use a Spring Boot Application as a Dependency

如同 war 一样,Spring Boot 应用并不打算被其他应用引用。如果你的应用需要共享一些类,推荐做法是把这些类分离出去,做成一个模块,其他应用引用这个模块就可以。

如果代码不能拆分,那么 Spring Boot 的 Maven 或者 Gradle 插件需要另外再构建一个单独用于被引用的包。


    
        
            org.springframework.boot
            spring-boot-maven-plugin
            
                exec
            
        
    

90.6 Extract Specific Libraries When an Executable Jar Runs

很多 jar 库不需要解压就可以使用,但也有些是需要解压才能运行,例如 JRuby。

以 JRuby 为例,POM 添加如下配置


    
        
            org.springframework.boot
            spring-boot-maven-plugin
            
                
                    
                        org.jruby
                        jruby-complete
                    
                
            
        
    

90.7 Create a Non-executable JAR with Exclusions

你可能经常需要构建两个 jar:an executable and a non-executable。可执行 jar 有额外的配置文件,例如 application.yml

在 Maven 里面,可执行 jar 必须是主构建


    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
        
            maven-jar-plugin
            
                
                    lib
                    package
                    
                        jar
                    
                    
                        lib
                        
                            application.yml
                        
                    
                
            
        
    

90.8 Remote Debug a Spring Boot Application Started with Maven

通过 Maven 来添加一个远程 debugger


  ...
  
    ...
    
      ...
      
        org.springframework.boot
        spring-boot-maven-plugin
        2.1.0.M3
        
          
            -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
          
        
        ...
      
      ...
    
    ...
  
  ...

90.9 Build an Executable Archive from Ant without Using spring-boot-antlib

使用 Ant 来构建,你可以选择依赖 spring-boot-antlib 模块,或者执行文档给出步骤。
我不看了,因为我想不出来为什么不直接使用现成的工具咧,有需要的时候再来看这个章节。

91. Traditional Deployment

91.1 Create a Deployable War File

first step: 编写一个类,继承 SpringBootServletInitializer,重写其 configure 方法。在主类也继承 SpringBootServletInitializer。

@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

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

}

next step: pom.xml

war

final step: 当显示配置了容器之后,便禁用了内嵌的容器


    
    
        org.springframework.boot
        spring-boot-starter-tomcat
        provided
    
    

91.2 Convert an Existing Application to Spring Boot

对于非 Web 应用,丢弃创建 ApplicationContex 的代码,更改为调用 SpringApplication 或者 SpringApplicationBuilder。
对于 Web 应用,有需要再查看这里的文档。

91.3 Deploying a WAR to WebLogic

有需要再查看这里的文档。

91.4 Use Jedis Instead of Lettuce

spring-boot-starter-data-redis 默认使用 Lettuce 作为 Redis 客户端,下面讲解更换成 Jedis
Maven 添加如下配置:


    org.springframework.boot
    spring-boot-starter-data-redis
    
        
            io.lettuce
            lettuce-core
        
    


    redis.clients
    jedis

相关文章

  • Spring Boot 官网文档简单翻译 Part I
  • Spring Boot 官网文档简单翻译 Part II
  • Spring Boot 官网文档简单翻译 Part III
  • Spring Boot 官网文档简单翻译 Part IV
  • Spring Boot 官网文档简单翻译 Part V
  • Spring Boot 官网文档简单翻译 Part VI
  • Spring Boot 官网文档简单翻译 Part VII
  • Spring Boot 官网文档简单翻译 Part VIII
  • Spring Boot 官网文档简单翻译 Part IX
  • Spring Boot 官网文档简单翻译 Part X

你可能感兴趣的:(Spring Boot 官网文档简单翻译 Part IX)