Spring Boot 官方文档学习(二)特点

一、SpringApplication

banner,就是启动时输出的信息,可以在classpath下添加 banner.txt,或者设置 banner.location 来指向特定的文件。(默认编码utf-8,或者通过banner.charset指定)

除了txt,你还可以使用 banner.gif (jpg / png),或者设定 banner.imgage.location。

下面是默认的banner(忽略吧,没意义的东西):

banner变量,只有应用相关的信息,略,见pdf。

还可以使用通过 SpringApplication.setBanner(…) 来设置。通过实现 org.springframework.boot.Banner 接口,可以实现自己的 printBanner() 。

通过设置 spring.main.banner-mode 来决定是否在 System.out (console) 上显示banner。使用配置的logger (log)或者全不用 (off)。

输出的banner会被注册成一个单例的bean,名字springBootBanner。

如果,你想创建一个分层次的ApplicationContext (多个context,有父子关系),可以使用 SpringApplicationBuilder 。它可以让你链式调用方法,并且设置父子关系。如下:

new SpringApplicationBuilder()
    .bannerMode(Banner.Mode.OFF)
    .sources(Parent.class)
    .child(Application.class)
    .run(args);

SpringApplicationBuilder使用起来有一些限制,详见javadoc。

Application事件和监听器

除了Spring框架的事件(如ContextRefreshedEvent)之外,SpringApplication还提供了一些额外的事件。

但是,有些事件是在ApplicationContext创建之前,所以无法通过@Bean形式注册监听器。可以通过SpringApplication.addListeners(...) 或者 SpringApplicaitonBuilder.listeners(...) 来注册。

另外,如果想以与application创建形式无关的方式来注册listeners,可以这样做:创建一个 META-INF/spring.factories 文件。内容如下:

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

多个监听器,应该用逗号连接吧???

Application Events,以下面的顺序发送:

  1. ApplicationStartedEvent 应用启动时发送,是除了注册监听器和初始化之外最早的。
  2. ApplicationEnvironmentPreparedEvent 创建context之前,已知道context需要使用的Environment时。
  3. ApplicationPreparedEvent 发生在context刷新之前,但在bean 定义加载之后。
  4. ApplicationReadyEvent 发生在刷新和任何相关回调被处理之后,表明应用已准备好响应请求了。
  5. ApplicationFailedEvent 发生在启动期间发生异常时。

没必要使用这些事件,但是了解一下还是挺有用的。Spring Boot内部使用这些事件来处理很多任务。

Web 环境

SpringApplication 会试图创建正确的 ApplicationContext。默认的,使用 AnnotationConfigApplicationContext 或者 AnnotationConfigEmbeddedWebApplicationContext ,这取决于是否web应用。

可以使用覆盖 setWebEnvironment(boolean webEnvironment) 默认设置。

也可以使用 setApplicationContextClass(…) 来控制 ApplicationContext 的类型。

注意:当在JUnit环境下使用SpringApplication时,通常需要设置 setWebEnvironment(false) 。

访问应用的参数

如何访问传递给SpringApplication.run(...) 的参数?

你可以注入一个 org.springframework.boot.ApplicationArguments bean。这是一个接口,提供了 String[] 和 option/non-option 参数形式。

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 注解注入application argument。

就是,如果有argument --larry.name=larry,那么可以使用@Value("${larry.name}"}String larryName;

ApplicationRunner or CommandLineRunner

如果想在SpringApplication启动后执行一些特定的代码,可以让这些代码实现 ApplicationRunner or CommandLineRunner 接口。二者都提供了一个run(),可以在SpringApplication.run(...) 完成之前被调用。

区别:CommandLineRunner 只提供对传递参数的默认访问形式 String[],而 ApplicationRunner 则使用了上面提到的 ApplicationArguments 接口。

import org.springframework.boot.*
import org.springframework.stereotype.*
@Component
public class MyBean implements CommandLineRunner {
    public void run(String... args) {
        // Do something...
    }
}

如果,定义了多个 CommandLineRunner or ApplicationRunner beans,那么可以通过实现 org.springframework.core.Ordered 接口或使用 org.springframework.core.annotation.Order 注解来控制加载顺序。

Application exit

每一个 SpringApplication 都注册了一个shutdown hook with JVM,以确保 ApplicationContext 顺利的关闭。所有的Spring生命周期中的回调(如 DisposableBean 接口,或者 @PreDestroy 注解)都可以使用。

另外,如果想在应用退出时返回特定的exit code,那beans可以实现 org.springframework.boot.ExitCodeGenerator 接口。

个人经验:同样可以使用@Order控制顺序,只不过相反。

个人经验:使用@Order控制的顺序,不能打破大的顺序。例如上面(ApplicationRunner or CommandLineRunner)的顺序,永远在SpringApplication启动完成之前调用。

Admin features(略)

Externalized Configuration(需要认真看看)

外来配置?就是说,通过设定这些配置,可以在不同的工作环境下运行相同的代码达到相同的目的。

Spring Boot支持的:properties文件、yaml文件、environment 变量、命令行参数。

然后,可以通过 @Value 注解注入到bean中,或者通过Spring 的 Environment 访问,或者通过 @ConfigurationProperties  绑定到结构化对象中。

个人经验:@Value 的工作是在SpringApplication启动完成之后进行的,在此之前值为null。

注意:不同方式的配置的优先级不一样。基本上,除了测试情况外,命令行参数优先级最高。尤其要注意指定profile下的优先级比默认的高。具体如下:

  1. @TestPropertySource annotations on your tests.
  2. Command line arguments.
  3. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
  4. ServletConfig init parameters.
  5. ServletContext init parameters.
  6. JNDI attributes from java:comp/env.
  7. Java System properties (System.getProperties()).
  8. OS environment variables.
  9. A RandomValuePropertySource that only has properties in random.*.
  10. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
  11. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
  12. Application properties outside of your packaged jar (application.properties and YAML variants).
  13. Application properties packaged inside your jar (application.properties and YAML variants).
  14. @PropertySource annotations on your @Configuration classes.
  15. Default properties (specified using SpringApplication.setDefaultProperties).

Configuring random values

RandomValuePropertySource 用于注入随机数值,它可以生成int、long、uuid 或者 字符串。如下:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

Accessing command line properties

默认,SpringApplication会将任何命令行参数(以--开头,如--server.port=8900)转成一个property,并添加到Spring Environment中。

再次强调:命令行参数的优先级最高。

如果不想添加到Spring Environment中,你可以禁用它们: SpringApplication.setAddCommandLineProperties(false) 。

关于application.properties文件

SpringApplication默认从以下地址加载,并添加到Spring Environment 中。

/config
/
classpath/
classpath/config

注意,优先级从上往下依次降低。

如果不想使用默认的名字,可以自行指定(两种方式):

java -jar myproject.jar --spring.config.name=myproject
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

注意,默认的加载地址永远有效,但可以添加新的,且新的地址的优先级更高。

注意,多数系统的环境变量不允许使用点分隔的键名,可以使用下划线代替。如: SPRING_CONFIG_NAME 代替 spring.config.name 。

另外,如果在容器中执行,还可以使用JNDI properties或者 Servlet Context初始化参数。

Profile-specific properties

在 application.properties 之外,还会加载 application-{profile}.properties 。由于 Environment 提供了一个默认的profile,所以,默认还会加载 application-default.properties 。

奇怪,这什么意思:

  • If you have specified any files in spring.config.location, profile-specific variants of those files will not be considered. Use directories in `spring.config.location` if you also want to also use profile-specific properties.

properties中的占位符

application.properties 中的值是按顺序加载到已有的 Environment 中,所以,后面的值可以使用前面的值,使用方法就是占位符。如下:

  1. app.name=MyApp
  2. app.description=${app.name} is a Spring Boot application

可以利用该技术创建短的变量?

YAML是JSON的超集!(略)

classpath中只要有SnakeYAML 库,SpringApplication就可以自动支持YAML。

而,Starters默认就含有SnakeYAML 库。

类型安全的Configuration Properties

这里的意思是说,通过Java类来确保类型安全,但值还是要在YAML中提供!!!

@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
    private String username;
    private InetAddress remoteAddress;
    // ... getters and setters
}

那么,@Value("${property}")  和@ConfigurationProperties 的区别? 暂略。

注意:通过 @ConfigurationProperties 类进行的properties设置,需要在 @Configuration 类上开启 @EnableConfigurationProperties 注解才行,而且,需要手动添加 @ConfigurationProperties 类,如下:

@Configuration
@EnableConfigurationProperties(ConnectionProperties.class)
public class MyConfiguration {
}

需要注意的是, @ConfigurationProperties 类对应的bean有一个约定好的名字: <prefix>-<fqn> 。fqn是full qualified name。

前面的例子,对应的名字是: connection-com.example.ConnectionProperties ,这里假定它在包 com.example 中。

但是,@ConfigurationProperties 类对应的bean还有一个默认的名字!!!只是,不建议在environment之外使用而已。

除了上面的红字部分,由于 @EnableConfigurationProperties 注解 会被自动应用到项目中,所以,只要确保 @ConfigurationProperties 类 是一个bean(即@Component),就会被自动添加到 Environment 。如下:

@Component //确保是一个bean即可!
@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
    // ... getters and setters of username and remoteAddress, and so on
}

这种形式的配置可以和YAML配置完美的配合。为什么要配合?因为上面只是类型安全,没有值!!!

# application.yml
connection:
    username: admin
    remoteAddress: 192.168.1.1
# additional configuration as required

个人经验:奇怪,为什么STS提示我在pom中添加spring-boot-starter-configxxxxx ?

提示:使用 @ConfigurationProperties,还可以生成meta-data文件,以供IDE使用。

第三方配置?

@ConfigurationProperties 还可以用于 @Bean 方法上。如下:

@ConfigurationProperties(prefix = "foo")
@Bean
public FooComponent fooComponent() {
    ...
}

这样,就是给bean加一个前缀,这个bean就可被用作ConfigurationProperties了!!!! 貌似也没别的了,一个bean而已。

灵活的绑定:是指对名字的匹配

例如:

@ConfigurationProperties(prefix="person")
public class OwnerProperties {
    private String firstName;
    public String getFirstName() {
        return this.firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
}

这里的 firstName 可以绑定如下内容:

person.firstName Standard camel case syntax.
person.first-name Dashed notation, recommended for use in.properties and .yml files.
person.first_name Underscore notation, alternative format for use in .properties and .yml files.
PERSON_FIRST_NAME Upper case format. Recommended when using a system environment variables.

Properties conversion,转换,类似SpringMVC的转换

如果要自定义类型转换,三种方式:创建一个 ConversionService bean,或者创建一个 property editors(通过 CustomEditorConfigurer bean),或者创建一个 Converters (@ConfigurationPropertiesBinding)。

注意:这个bean在应用早期被调用,所以,注意限制它的依赖!

@ConfigurationProperties validation

Spring Boot默认使用JSR-303去校验,所以可以使用JSR-303的注解。如下:

@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
    @NotNull
    private InetAddress remoteAddress;
    // ... getters and setters
}

如果有嵌套属性,需要使用@Valid来触发校验。如:

@ConfigurationProperties(prefix="connection")
public class ConnectionProperties {
    @NotNull
    @Valid
    private RemoteAddress remoteAddress;
    // ... getters and setters
    public static class RemoteAddress {
        @NotEmpty
        public String hostname;
        // ... getters and setters
    }
}

也可以使用自定的Spring Validator,bean id是 configurationPropertiesValidator 即可。

注意: spring-boot-actuator 模块有一个端点,对外暴露了所有的 @ConfigurationProperties beans。浏览器中访问 /configprops 即可。也可以使用相应的JMX端点???

个人经验:其实还有很多地址,详见启动信息。如下:

@Value("${property}")  和@ConfigurationProperties 的区别

@Value 是core container的feature。不支持灵活绑定,不支持Meta-data。但支持spELl。

@ConfigurationProperties 则支持灵活绑定,支持Meta-data。但不支持spELl。

官方指导里推荐使用后者。

Profiles

@Profile 可以用于 @Component 或 @Configuration 。

使用 spring.profiles.activeEnvironment property 来指定运行时的 profile 。如:

#application.properties
spring.profiles.active=dev,hsqldb
#command line argument
--spring.profiles.active=dev,hsqldb

有时候,添加profile 比替换profile 更有用。

spring.profiles.include property 可以做到无条件的添加profile。

SpringApplication也提供了API来添加profile: setAdditionalProfiles() 。

还可以使用 Spring的 ConfigurableEnvironment 接口(实验了下,太麻烦,不建议使用)。

问题:@Profile在类上和在方法上,是怎么结合的???怎么出问题了。

Logging

Spring Boot 使用JCL接口,但未指定实现。默认的实现包括JUL、Log4j2、Logback。均已设置console输出。

如果使用Starter模块,则使用Logback

Log Level:ERROR, WARN, INFO, DEBUG or TRACE

注意,Logback没有FATAL,如果设置了FATAL,会被映射成ERROR。

开启debug模式:--debug,或者在 application.properties:debug=true。

注意,是debug模式,不是DEBUG Level。

彩色输出

终端支持ANSI才行,不过现在还有不支持的吗?

需要设置 spring.output.ansi.enabled 。

STS中以Spring Boot Application启动时,应该默认设置了。

问题是,为什么我直接以Java Application启动就不行?-- 因为没有设置颜色。囧~~

File output

默认Log只会ouput到console。如果想输出到File,应该设置 logging.file 或者logging.path property 。

注意:输出文件大小到达10 Mb时,会重新开始?

注意:logging系统是在应用的早期初始化的,所以,不能在通过 @PropertySource 加载的文件中配置。

注意:logging properties 与实际的logging系统无关,所以,Spring Boot不会管理具体的配置文件,如 logback.configurationFile 或 logback.xml 。 会加载,会执行,但与Spring Boot无关,是logging系统自己的东西。

Log Levels

所有Spring Boot支持的logging系统,都可以在Spring Environment 中设置(如application.properties),格式:logging.level.*=LEVEL。

其中,LEVEL可以是TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF。

root logger可以使用 logging.level.root 设置。如下:

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

自定义log配置

可以使用不同的logging系统,只要在classpath中添加相应的jars即可。更进一步,还可以在classpath提供一个相应的配置文件,或者在一个指定的位置(需要使用 logging.config 来指定)。

也可以使用一个特定的logging系统,使用 org.springframework.boot.logging.LoggingSystem  来指定,注意,该键对应的值是具体logging实现的全路径,如为none,则默认完全禁用Spring Boot的logging配置。

再次提醒:logging系统初始化较早,不能使用 @Configuration 里的 @PropertySources 来控制。

根据不同的logging实现,加载不同的配置文件。如下:

Logback logback-spring.xmllogback-spring.groovylogback.xml or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

注意:官方建议使用 -spring的文件名,否则Spring不能完全控制log初始化(因为初始化太早)。

警告:直接运行fat jar时,JUL会有问题,建议避免使用它。

个人问题: Spring Environment 和 System properties 什么关系?为什么书上说一些properties会从前者传到后者,以帮助自定义?

Spring Environment System Property Comments
logging.exception-conversion-word LOG_EXCEPTION_CONVERSION_WORD The conversion word that’s used when logging exceptions.异常?例外?
logging.file LOG_FILE Used in default log configuration if defined.
logging.path LOG_PATH Used in default log configuration if defined.
logging.pattern.console CONSOLE_LOG_PATTERN The log pattern to use on the console (stdout). (Only supported with the default logback setup.) 仅支持默认logback设置。
logging.pattern.file FILE_LOG_PATTERN The log pattern to use in a file (if LOG_FILE enabled). (Only supported with the default logback setup.) 仅支持默认logback设置。
logging.pattern.level LOG_LEVEL_PATTERN The format to use to render the log level (default %5p).(Only supported with the default logback setup.)  仅支持默认logback设置。
PID PID The current process ID (discovered if possible and when not already defined as an OS environment variable).

注意,如果要使用占位符,应该使用Spring Boot的,而非Spring的。

例子就是Logback的分隔符,应该用“:”,而非“:-”。

提示:SB包含了Logback的大量扩展,用于协助配置。可以在 logback-spring.xml 中使用它们。

注意:不能在 logback.xml 中使用这些扩展,因为它被加载的太早了。

Profile-specific Configuration (logging)

可以在 <configuration> 内部使用 <springProfile>,然后在 name 属性里设置profiles。如下:

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>
<springProfile name="dev, staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>
<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

<springProperty> 标签可以使用Spring Environment 中的properties。

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
        defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>

关键:scope、source、defaultValue。

时间: 2024-07-31 05:29:45

Spring Boot 官方文档学习(二)特点的相关文章

20191114 Spring Boot官方文档学习(4.7)

4.7.开发Web应用程序 Spring Boot非常适合于Web应用程序开发.您可以使用嵌入式Tomcat,Jetty,Undertow或Netty创建独立的HTTP服务器.大多数Web应用程序都使用该spring-boot-starter-web模块来快速启动和运行.您还可以选择使用spring-boot-starter-webflux模块来构建反应式Web应用程序. 4.7.1.Spring Web MVC框架 在Spring Web MVC框架(通常简称为"Spring MVC"

20191112 Spring Boot官方文档学习(4.5-4.6)

4.5.国际化 Spring Boot支持本地化消息,因此您的应用程序可以迎合不同语言首选项的用户.默认情况下,Spring Boot messages在类路径的根目录下查找message resource bundle的存在. 当配置的resource bundle的默认属性文件可用时(即默认为messages.properties),将应用自动配置.如果您的resource bundle仅包含特定于语言的属性文件,则需要添加默认文件.如果找不到与任何配置的基本名称匹配的属性文件,则不会自动配

Spring 4 官方文档学习(十二)View技术

1.介绍 Spring 有很多优越的地方,其中一个就是将view技术与MVC框架的其他部分相隔离.例如,在JSP存在的情况下使用Groovy Markup Templates 还是使用Thymeleaf,仅仅是一个配置问题. 本章覆盖了主要的view技术,嗯嗯,可以与Spring结合的那些,并简明的说明了如何增加新的view技术. 本章假定你已经熟悉了Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图 -- 它覆盖了views如何耦合到MVC框架

Spring Boot 官方文档入门及使用

个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念,请先移步上一篇文章 Spring Boot 学习.本篇原本是为了深入了解下Spring Boot而出现的. 另外,Spring Boot 仍然是基于Spring的,建议在赶完工之后深入学习下Spring,有兴趣可以看看我的 Spring 4 官方文档学习(十一)Web MVC 框架 .欢迎探讨,笑~

Spring 4 官方文档学习(十一)Web MVC 框架之resolving views 解析视图

接前面的Spring 4 官方文档学习(十一)Web MVC 框架,那篇太长,故另起一篇. 针对web应用的所有的MVC框架,都会提供一种呈现views的方式.Spring提供了view resolvers,可以让你在浏览器中render model,而不必绑定到某种特定的view技术上.开箱即用,例如,Spring可以让你使用JSPs.Velocity目标和XSLT views.See Chapter 23, View technologies for a discussion of how

【Spring Boot 官方文档】26、Log日志

简介: Spring Boot所有内部日志使用Apache的Commons Logging组件,同时也开放了底层的日志实现. Spring Boot为3种日志组件Java Util Logging,Log4J2,Logback提供了默认配置,而且为每一种预设了控制台输出,并提供文件输出可选. 如果使用Spring Boot的starters组件,默认使用Logback组件. Spring Boot提供了适当的Logback路由,以保证依赖库使用Java Util Logging, Commons

Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的人,但事实并非如此,例如我.好在闷着头看了一遍,又查资料又敲代码,总算明白了. 其实说穿了一文不值,我们用一个例子来解释: 假定,现有一个app,功能是接收你输入的生日,然后显示你的年龄.看起来app只要用当前日期减去你输入的日期就是年龄,应该很简单对吧?可惜事实不是这样的. 这里面有三个问题: 问题一:我们输入的永远是字符串,字符串需要转成日期格式才能被我们的ap

Spring 4 官方文档学习(五)核心技术之SpEL

1.介绍 SpEL支持在runtime 查询.操作对象图. 2.功能概览 英文 中文 Literal expressions 字面值表达式 Boolean and relational operators 布尔和关系操作符 Regular expressions  正则表达式 Class expressions 类表达式 Accessing properties, arrays, lists, maps 访问properties.arrays.lists.maps Method invocati

Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

在前面的文档中讲解了Spring MVC的特殊beans,以及DispatcherServlet使用的默认实现.在本部分,你会学习两种额外的方式来配置Spring MVC.分别是:MVC Java config 和  MVC XML namespace. 原文: Section 22.2.1, "Special Bean Types In the WebApplicationContext" and Section 22.2.2, "Default DispatcherSer