Spring-Boot-Introduction-3

Spring Boot 入门(三):Spring Boot功能


Spring Application

SpringApplication 类提供了方便的方法来引导从 main() 方法启动的Spring应用程序。在多数情况下,你可以委托静态 SpringApplication.run 方法,如下:

1
2
3
public static void main(String[] args) {
SpringApplication.run(MySpringConfiguration.class, args);
}

启动失败

当启动失败时,已注册的 FailureAnalyzers 就会提供详细的错误信息和解决问题的措施。例如,当你在8080端口开启一个web应用但是该端口已被使用时:

1
2
3
4
5
6
7
8
9
10
11
***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

如果没有 FailureAnalyzers 能处理异常,你仍然可以看到完整的条件报告来了解出了什么问题。为此,你需要启动debug属性或为 org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener 启动debug应用日志。

例如:

1
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

自定义SpringApplication

如果你不想要以默认方法启动SpringApplication,你可以自定义一个实例:

1
2
3
4
5
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MySpringConfiguration.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}

Builder API

Spring Boot 以提供来Builder API来创建SpringApplication实例,你可以像下面的例子那样使用:

1
2
3
4
5
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);

应用事件和监听器

除了通常的Spring Framework事件(例如ContextRefreshedEvent)之外,SpringApplication还会发送一些其他应用事件

  • 某些事件会在创建 ApplicationContext 之前触发,你无法将这些事件注册为 @Bean 。你可以使用 SpringApplication.addListeners()SpringApplicationBuilder.listeners()方法来注册。

  • 如果你希望无论应用怎么创建,都能自动注册这些监听器,你可以将一个 META-INF/spring.factories 文件添加到项目中,并使用org.springframework.context.ApplicationListener 键。例如:

    1
    org.springframework.context.ApplicationListener=com.example.project.MyListener

当你的应用运行时,有以下事件会发生:

  1. ApplicationStartingEvent :此时应用完成来监听器和初始化程序的注册,但还没进行任何处理。
  2. ApplicationEnvironmentPreparedEvent :此时已经知道要在context中使用的环境,但是context还没被创建。
  3. ApplicationPreparedEvent :已加载bean定义并准备开始刷新。
  4. ApplicationStartedEvent :已经刷新context并准备调用应用程序和命令行运行程序。
  5. ApplicationReadyEvent :已经调用应用程序和命令行运行程序,应用已经准备好接收服务请求。
  6. ApplicationReadyEvent :应用启动遇到异常。

网络环境

SpringApplication 会尝试帮你创建正确类型的ApplicationContext。用于确定WebApplicationtype的算法非常简单:

  • 如果Spring MVC存在,就会使用 AnnotationConfigServletWebServerApplicationContext
  • 如果Spring MVC不存在并且Spring WebFlux存在,那么就会使用 AnnotationConfigReactiveWebServerApplicationContext
  • 其他情况使用 AnnotationConfigApplicationContext

这意味着如果你同时使用Spring MVC和Spring WebFlux中的新WebClient的话Spring会默认使用Spring MVC。当然,你也可以使用 setWebApplicationType(WebApplicationType) 来指定。

应用访问参数

如果需要访问传递给SpringApplication.run()的应用参数,可以注入org.springframework.boot.ApplicationArguments bean。 ApplicationArguments接口提供对原始String []参数以及解析 optionnon-option 参数的访问,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.boot.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;

@Component
public class MyBean {

@Autowired
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
}

}
  • Spring Boot还在Spring Environment中注册了一个CommandLinePropertySource。这使您还可以使用@Value注释注入单个应用参数.

使用ApplicationRunner或CommandLineRunner

如果在SpringApplication启动后需要运行某些特定代码,则可以实现ApplicationRunnerCommandLineRunner接口。两个接口以相同的方式工作,并提供单个run方法,该方法在SpringApplication.run()执行完成之前调用。

CommandLineRunner接口提供对应用程序参数的访问,作为简单的字符串数组,而ApplicationRunner使用前面讨论的ApplicationArguments接口。以下示例显示了带有run方法的CommandLineRunner

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.boot.*;
import org.springframework.stereotype.*;

@Component
public class MyBean implements CommandLineRunner {

public void run(String... args) {
// Do something...
}

}

如果定义了必须按特定顺序进行调用的多个CommandLineRunnerApplicationRunner bean,则可以另外实现org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order注释。

应用退出

每个SpringApplication都会向JVM注册一个关闭钩子,以确保ApplicationContext在退出时正常关闭。标准的Spring生命周期回调(例如DisposableBean接口或@PreDestroy注释)都可以使用。

此外,如果bean希望在调用SpringApplication.exit()时返回特定的退出代码,则bean可以实现org.springframework.boot.ExitCodeGenerator接口。然后可以将此退出代码传递给System.exit()以将其作为状态代码返回,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@SpringBootApplication
public class ExitCodeApplication {

@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}

public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(ExitCodeApplication.class, args)));
}

}

此外,ExitCodeGenerator接口可以通过异常实现。遇到这样的异常时,Spring Boot返回实现的getExitCode()方法提供的退出代码。

管理功能

通过指定spring.application.admin.enabled属性,可以为应用启用与管理相关的功能。这会在平台MBeanServer上公开SpringApplicationAdminMXBean。您可以使用此功能远程管理Spring Boot应用。此功能也有助于任何服务包装器实现。

  • 如果您想知道应用正在运行的HTTP端口,请使用local.server.port的键获取该属性。

外部化配置

Spring Boot可以使用外部化配置使你在不通的环境中使用相同的代码。你可以使用属性文件、VAML文件、环境变量和命令行参数来外部化配置。可以使用 @Value 注释将属性注入到Bean中,通过Spring的Environment抽象访问,或者通过 @ConfigurationProperties 绑定到结构化对象上。

这里还有很多没写上来,感觉不是现阶段需要的

Profiles

Spring Profiles提供了一种隔离部分应用配置并使其仅在特定环境中可用的方法。可以使用@Profile标记任何@Component@Configuration以限制何时加载它,如以下示例所示:

1
2
3
4
5
6
7
@Configuration
@Profile("production")
public class ProductionConfiguration {

// ...

}

您可以使用spring.profiles.active Environment属性指定哪些配置文件处于活动状态。您可以使用本章前面介绍的任何方法指定属性。例如,您可以将它包含在application.properties中,如下所示:

1
spring.profiles.active=dev,hsqldb,production

您还可以在命令行上开关它:

1
--spring.profiles.active=dev,hsqldb

添加活动配置文件

spring.profiles.active属性遵循与其他属性相同的排序规则:最高的PropertySource获胜。这意味着您可以在application.properties中指定活动配置文件,然后使用命令行开关替换它们。

有时,将特定于配置文件的属性添加到活动配置文件而不是替换它们是有用的。 spring.profiles.include属性可用于无条件地添加活动配置文件。 SpringApplication入口点还有一个Java API,用于设置其他配置文件(即,在spring.profiles.active属性激活的配置文件之上)。

例如,当使用开关--spring.profiles.active = prod运行具有以下属性的应用程序时,也会激活proddbprodmq配置文件:

1
2
3
4
5
6
7
---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
- proddb
- prodmq
  • 可以在YAML文档中定义spring.profiles属性,以确定此特定文档何时包含在配置中。

以编程方式设置配置文件

您可以通过在应用程序运行之前调用SpringApplication.setAdditionalProfiles()以编程方式设置活动配置文件。也可以使用Spring的ConfigurableEnvironment接口激活配置文件。

Profile-specific配置文件

application.properties(或application.yml)的Profile-specific变体和通过@ConfigurationProperties引用的文件被视为文件并已加载。

这里我没一个字看得懂

日志

Spring Boot使用Commons Logging进行所有内部日志记录,但保留底层日志实现。为Java Util Logging,Log4J2和Logback提供了默认配置。在每种情况下,记录器都预先配置为使用控制台输出,并且还提供可选的文件输出。

默认情况下,如果使用“Starters”,则使用Logback进行日志记录。还包括适当的Logback路由,以确保使用Java Util Logging,Commons Logging,Log4J或SLF4J的依赖库都能正常工作。

日志格式

Spring Boot的默认日志输出类似于以下示例:

1
2
3
4
5
2014-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

记录会输出以下项目:

  • 日期和时间:毫秒精度,易于排序。
  • 日志级别:ERRORWARNINFODEBUGTRACE
  • 进程ID。
  • --- 分隔符,用于区分实际日志消息的开始。
  • 线程名称:用方括号括起来(可能会截断控制台输出)。
  • 记录器名称:这通常是源类名称(通常缩写)。
  • 日志消息。

Logback没有FATAL级别。它映射到ERROR

控制台输出

默认日志配置会在写入时将消息返回显示到控制台。默认情况下,会记录ERROR级别,WARN级别和INFO级别的消息。您还可以通过使用--debug标志启动应用程序来启用“调试”模式。

1
$ java -jar myapp.jar --debug
  • 您还可以在application.properties中指定debug = true

彩色编码输出

花里胡哨

文件输出

默认情况下,Spring Boot仅记录到控制台,不会写入日志文件。如果除了控制台输出之外还要编写日志文件,则需要设置logging.filelogging.path属性(例如,在application.properties中)。

下表显示了logging.*属性如何一起使用:

logging.file logging.path Example Description
(none) (none) 仅控制台记录。
指定文件Specific file (none) my.log 写入指定的日志文件。名称可以是精确位置或相对于当前目录。
(none) 指定路径Specific directory /var/log spring.log写入指定的目录。名称可以是精确位置或相对于当前目录。

日志文件在达到10 MB时会轮换,并且与控制台输出一样,默认情况下会记录ERROR级别,WARN级别和INFO级别的消息。可以使用logging.file.max-size属性更改大小限制。除非已设置logging.file.max-history属性,否则以前轮换的文件将无限期归档。

  • 日志记录系统在应用程序生命周期的早期初始化。因此,在通过@PropertySource注释加载的属性文件中找不到日志记录属性。
  • 日志记录属性独立于实际的日志记录基础结构。因此,spring Boot不管理特定的配置密钥(例如Logback的logback.configurationFile)。

日志级别

所有受支持的日志记录系统都可以使用logging.level设置Spring环境中的记录器级别(例如,在application.properties中)。当level是TRACE, DEBUG, INFO, WARN, ERROR, FATAL, 或OFF时使用logging.level.<logger-name>=<level>。可以使用logging.level.root配置root日志。

1
2
3
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

日志组

自定义日志配置

Logback 插件

Profile-specific 配置

环境属性

国际化

Spring Boot支持本地化消息,以便您的应用可以满足不同语言首选项的用户。默认情况下,Spring Boot会在类路径的根目录中查找消息资源包的存在。

  • 当配置的资源包的默认属性文件可用时(默认情况下为messages.properties),将自动配置。如果资源包仅包含特定于语言的属性文件,则需要添加默认值。

可以使用spring.messages命名空间配置资源包的基本名称以及其他几个属性,如下:

1
2
spring.messages.basename=messages,config.i18n.messages
spring.messages.fallback-to-system-locale=false
  • spring.messages.basename支持以逗号分隔的位置列表,包括限定符或从类路径根解析的资源。

JSON

Spring Boot提供了与三个JSON映射库的集成:

  • Gson
  • Jackson
  • JSON-B

Jackson是首选的默认库。

开发Web应用程序

Spring Boot非常适合Web应用程序开发。您可以使用嵌入式Tomcat,Jetty,Undertow或Netty创建自包含的HTTP服务器。大多数Web应用程序使用spring-boot-starter-web模块快速启动和运行。您还可以使用spring-boot-starter-webflux模块选择构建响应式Web应用程序。

Spring Web MVC Framework

Spring Web MVC Framework(通常简称为“Spring MVC”)是一个丰富的“模型视图控制器”Web框架。 Spring MVC允许您创建特殊的@Controller@RestController beans来处理传入的HTTP请求。控制器中的方法通过使用@RequestMapping注释映射到HTTP。

以下代码显示了一个提供JSON数据的典型@RestController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RestController
@RequestMapping(value="/users")
public class MyRestController {

@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}

@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}

@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}

}

下面我顶不住

Spring MVC 自动配置

HttpMessageConverters

自定义JSON序列化程序和反序列化程序

MessageCodesResolver

静态内容

欢迎页面

自定义Favicon

路径匹配和内容协商

ConfigurableWebBindingInitializer

模板引擎

错误处理

自定义错误页面

映射Spring MVC之外的错误页面

Spring HATEOAS

CORS支持

Spring WebFlux框架

Spring WebFlux自动配置

带有HttpMessageReaders和HttpMessageWriters的HTTP编解码器

静态内容

模块引擎

错误处理

自定义错误页面

网络过滤器

JAX-RS and Jersey

嵌入式Servlet容器支持

Servlets, Filters, listeners

注册 Servlets, Filters, Listeners 为 Spring Beans

Servlet上下文初始化

扫描Servlets, Filters, listeners

ServletWebServerApplicationContext

自定义嵌入式Servlet容器

程序化定制

直接自定义ConfigurableServletWebServerFactory

JSP限制

嵌入式Reactive Server支持

Reactive Server资源配置

Security

MVC Security

WebFlux Security

OAuth2

Client

OAuth2客户端注册常见提供商

资源服务器

授权服务器

Actuator Security

跨站点请求伪造保护

使用SQL数据库

配置数据源

嵌入式数据库支持

连接到生产数据库

连接到JNDI数据源

JdbcTemplate

JPA 和 Spring Data JPA

实体类

Spring Data JPA存储库

创建和删除JPA数据库

在View中打开EntityManager

Spring Data JDBC

使用H2的Web控制台

更改H2控制台的路径

jOOQ

代码生成

DSLContext

jOOQ SQL Dialect

自定义jOOQ