b spring-boot入门介绍

—> go to 总目录

4 Spring boot的特性

这个章节对Spring boot有更细的介绍。如果你可想直接用,那么前面1~3已经可以满足你了,如果你想要自定义,必须得看下面细节得介绍。

4.1 SpringApplication

SpringApplication类提供了一个便方式来启动。
b spring-boot入门介绍
默认log的级别-- INFO,这个可以设置请关注 Log levels
不过你可以使用利用实现得方式来关闭启动信息的打印,通过设置spring.main.log-startup-infofalse

启动时你可以覆盖SpringApplication得子类得方法
logStartupInfo(boolean)

4.1.1 Startup Failure 启动失败

你的应用启动失败时,会注册FailureAnalyzers类去提供一个描述失败信息的机会。

web引用的默认启动时8080,被占用时会报错
b spring-boot入门介绍
除了默认的你可以提供你自己的FailureAnalyzers,怎么添加后面有介绍。
如果想要更详细得信息
方式一: 配置文件中设置debug级别
方式二:java -jar 设置 debug
java -jar myproject-0.0.1-SNAPSHOT.jar --debug

4.1.2 懒加载

懒加载开启后,类只有在被使用时加载,而非启动时。好处是节约启动时间。web项目时,懒加载会让http request命中时才会加载相关的bean。
由于懒加载,一些问题不能在启动时暴露,比如自身的问题,或者jvm内存不足得问题,所以默认懒加载时关闭的
打开懒加载
使用在SpringApplicationBuilderlazyInitialization或者setLazyInitialization方法。会这个使用初始化的属性来打开。
b spring-boot入门介绍
开一个注解@Lazy(false)

4.1.3 自定义 Banner

banner是启动时打印的输出,可以自定义。可以有文字,gif.jpg,png等
详见原文
可以使用SpringApplication.setBanner(…)方法或者,使用org.springframework.boot.Banner接口,实现printBanner()即可。
你可以使用spring.main.banner-mode来决定你是打印到控制台,还是log,或者关闭。
banner,被注成csingleton,名为
springBootBanner

4.1.4 自定义 SpringApplication

b spring-boot入门介绍
除此之外也可以用application.properties来配置应用属性。

4.1.5 流畅的builder API 定义SpringApplication

如果你需要层次化得ApplicationContext,可以使用buildr模式,利用source标记parent,child标记子方法
b spring-boot入门介绍

4.1.6 应用事件和监听。

除了寻常Spring Framework的event比如ContextRefreshedEvent之外,SpringApplication还有额外的事件

一些事件是在Application创建时产生,所以你无法将listener 注册为@Bean(因为bean在其后)。但是你可以使用SpringApplication.addListeners(…)或者SpringApplicationBuilder.listeners(…)来添加监听器。
如果你想要自动注册监听器,无视应用是否被创建,你可以添加META-INF/spring.factories文件到你的工程,并引用他
org.springframework.context.ApplicationListener=com.example.project.MyListener

应用事件得发送顺序

  1. ApplicationStartingEvent产生在所有进程之前,除过listenersinitializers的注册。
  2. 在context被创建前,但Enviroment被确认后,ApplicationEnvironmentPreparedEve会发出
  3. ApplicationContextInitializedEvent被发出,当ApplicationContext被准备好,ApplicationContextInitiallizers被调用,但是在任何bean 定义被加载前
  4. ApplicationPrepareEvent在context刷新之前发送,但是在bean 定义被加载之后
  5. ApplicationStartedEvent在context刷新之后,但是在应用和command-line runners被调用之前。
  6. ApplicationReadyEvent在任何application和commamd-line调用之后,意味着应用可以去正常服务
  7. ApplicationFailedEvent在启动存在异常时抛出。

上述列表只是在SpringApplication中的
SpringApplicationEvent
除了这些,还有下列的事件在
ApplicationPreparedEvent
ApplicationStartedEvent被发送。

  1. ApplicationContext刷新时
    ContextRefreshedEvent被发送
  2. WebServerInitializedEvent被发送,在WebServver就绪时。
    ServletWebServerInitializedEventReactiveWebServerInitializedEvent时servert 和reactive发出的。
    事件得推送使用的Spring Framework的事件推送组件。这个组件会确保把事件发送到子context和组件context中。如果你的context是层次化的,就意味值一个listener,会收到很多类型的事件。
    为了允许你的linstener能够识别时自己的事件还是后代的事件,它应该要求application能够拿到不同的Context进行比较,就是和框架有交互。
    就需要使用ApplicationContextAware将Context注入到listener,或者这个listener本身就是一个bean,使用@Autowired

4.1.7 Web Enviromment

SpringApplicaton试图根据你的行为去创建一个正常类型的ApplicationContext。这个算法被用来确定WebApplicationType是十分简单的。

  • 当前是Spring MVC,AnnotationConfigServletWebServerApplicationContext会被使用
  • 不是mvc 而是WebFlux,那么AnnotationConfigReactiveWebServerApplicationContext被使用
  • 都不是时 AnnotationConfigApplicationContext被使用。

意味着,同时用mvc和webflux的webclient时。spring mvc会默认被选中。
可以覆盖来选择
b spring-boot入门介绍

4.1.8 启动参数的获取

启动参数会被注入到org.springframework.boot.ApplicationArgumentsbean。
可以解析命令和普通参数
b spring-boot入门介绍

4.1.9 使用Applicationer 或者CommandLineRunner

如果你要在SpringApplication启动后跑一些特殊的代码,一次性的。
可以实现ApplicationRunner 或者CommandLineRunner接口,实现其Run方法。

ApplicationRunner使用前面提到的ApplicationArguments
CommandLineRunner就是使用run加string参数
b spring-boot入门介绍
你可以实现org.springframework.core.Ordered方法或者org.springframework.core.annotation.Order来设定顺序

4.1.10 应用退出

每个SpringApplication会在在jvm注册一个shutdown hook。优雅的close时,所有的lifecycle会被调用,比如@PreDestory。
额外的你可以在退出时指定一个返回码
b spring-boot入门介绍

4.1.1 Admin 特性

你可以用spring.application.admin.enabled属性来开启admin特性。它会在MBeanServer暴露一个SpringApplicationAdminMXBean。你可以使用这个特性来远程的管理的spring boot应用。

b spring-boot入门介绍

4.2 扩展配置

Spring boot允许你使用阔A站配置,以便于你用同一份代码跑在不同环境下。你可以使用properties files,YAML files,enviroment variables 和command-ling arguments来作为扩展配置。
Property的值可以被直接注入你的beans—通过使用@Value的注解,Spring Environment或者通过@ConfigurationProperties
Spring Boot使用一个非常特殊的PropertySource order去明智的加载values值。具体如下

  1. 前面Devtools的全局设定,在$HOME/.config/spring-boot文件夹下。
  2. 你的test上使用@TestPropertySource注解
  3. 你tests上的properties注解,可以被@SpringBootTest获得
  4. Commend line arguments
  5. SPRING_APPLICATION_JSON的Properties(在environment或者系统属性里内置的JSON)
  6. ServletConfig 初始化参数
  7. ServletContext的初始化参数
  8. JNDI 属性在 java:comp/env
  9. java的系统属性System.getProperties()
  10. OS的environment 变量
  11. RandomValuePropertySource只在random.*
  12. 在你packaged jar包之外的,profile application properties----application.{profile}.properties或者yaml
  13. 在你packaged jar包之内的,profile application properties----application.{profile}.properties或者yaml
  14. 在你packaged jar包和之外的其他application.properties或者yaml
  15. 在你packaged jar包和之内的其他application.properties或者yaml
  16. 你@Configuration注解上的@PropertySource。请注意这样的property sources 不会被添加到 Environment 直到应用的Context被刷新。所以这里配置logging.*spring.main.*会太晚,他们在refresh 开始后
  17. SpringApplication的默认属性—SpringApplication.setDefaultProperties

示例Compent使用一个name属性
b spring-boot入门介绍
application.properties中加一个name就可以获得,测试时可以使用java -jar app.jar --name="Spring"临时覆盖。
b spring-boot入门介绍

4.2.1 配置随机值

RandomValuePropertySource在注入随机值时十分有用。
b spring-boot入门介绍
random.int*是在的格式是open value (,max) close,OPEN CLOSE是符号比如()或者 [] 或者(] [),value和max是整数,如果有max那么value就是最小值,没有那么value就是max

4.2.2 Command line属性

Spring boot会把--的识别为property,并放在Envirmoent。
如果你不想被添加,你可以使用SpringApplication.setAddCommandLineProperties(false)

4.2.3 Application Property Files

SpringApplication加载属性文件从application.properties文件里加载。

  1. 在当前目录下的/config
  2. 当前目录
  3. classpath下的/config
  4. class root
    如果你不想用application.properties作为配置文件的name或者想指定配置文件位置,可以如下
    b spring-boot入门介绍

4.2.4 profile-具体的properties

application-{profile}.properties
可以靠spring.profiles.active来设置。

4.2.5 占位符

application.properties中存在的值,会先放到Environment中,所以你可以用占位符直接使用
b spring-boot入门介绍

4.2.6 属性加密

spring boot 不会提供任何对properties处理的动作,但是可以提供hook。
实现这个EnvironmentPostProcessor的接口,可以自定义,后面详细介绍。

4.2.7 使用yaml而不是 properties

yaml比json更好
SnakeYmal库已经被spring-boot-starter默认加载了。

Loading Yaml

spring框架提供两个便利的类去加载:YamlPropertiesFactoryBean加载properties作为Properties,YamlMapFactoryBean加载YAML作为一个Map
这个属性会被加载成
b spring-boot入门介绍
被加载成
b spring-boot入门介绍

属性绑定

使用@ConfigurationProperties来做属性绑定
b spring-boot入门介绍

把yml属性暴露在Spring Enviroment

YamlPropertiesSourceLoader被用来把yaml作为一个PropertySource。如果这么做了就可以使用@Value的注解去访问yaml配置

多profile

你可以在一个文件里配置多个profile信息,需要使用spring.profiles key。
b spring-boot入门介绍
需要属性的时候,如果都没有就会加载默认的,比如spring.security.user.password只在default profile中配置。
b spring-boot入门介绍
其他可以不必配置
b spring-boot入门介绍

yaml的缺点

不能使用@PropertySource注解来加载。
还有比如配置文件如下
b spring-boot入门介绍
当你使用--spring.profiles.active=dev
就会找不到pwd,因为在"!test"里面。
--spring.profiles.active=dev意味着
application-dev.yml

4.2.8 配置属性的类型安全

比如使用@Value(${proprty})是把配置注入到Environmet中,但是多个配置式就会混淆。Spring boot 提供了另一种方式,拥有强类型匹配去管理和校验你的配置。

JavaBean properties binding

将acme后缀的属性全部绑定
b spring-boot入门介绍
其中嵌套类Security就被抓化为acme.security.username

propreties被映射到
@ConfigurationProperties类上,可以来源于properties,yaml files, environment等,但是get与setter并不会被使用
可以设默认值

Constructor binding

构造器绑定
b spring-boot入门介绍
注意@ConstructorBinding注解,这个注解将会指示让构造器被调用

打开@ConfigurationProperties注解

spring boot去绑定@ConfigurationProperties并注册为bean。
你可以依赖一般的ComponmentScan来扫描@ConfigurationProperties
有时被配置@ConfigurationProperties并不会被扫描到,比如你自定义的starter。这是你可以在任何@Configuration上打开@EnableConfigurationProperties去详细指明properties的list,让他们被扫描
b spring-boot入门介绍
可以用sacn来指明需要扫描的未知,可以标记在任何类上。
b spring-boot入门介绍
我们推荐@Configuration只用来处理environment,不要把context的其他bean注入进来。

使用@ConfigurationProperties-注解类型

假设
b spring-boot入门介绍
使用@ConfigurationProperties被绑定并生成了AcmeProperties类
注入其他类中并使用
b spring-boot入门介绍

第三方配置

可以把@ConfigurationProperties标记在@Bean上,即bean定义的地方,可以用配置里的属性来初始化bean
b spring-boot入门介绍

松弛的绑定规则

spring使用宽松的绑定规则,不会那么精确,比如context-path切换成contextPath,或者PORTport一致。
b spring-boot入门介绍
比如上面的这些例子里下面的这些值会被用到
b spring-boot入门介绍
对于不同的property source不用的源会被用到
b spring-boot入门介绍

复杂类型的合并

b spring-boot入门介绍
b spring-boot入门介绍
属性冲突时,没有profile被**,先到先得,被**时,被**的先命中。

Properties Conversion

属性转化,提供ConversionService来对特定值转化成正常类型。

Converging durations 转换时间单位

时间单位的规范,以一种更可读的方式。java.time.Duration属性,

  • 一个long代表数字,如果@DurationUnit单位没被设置,才会采用默认的30S
  • ISO-8061格式
    b spring-boot入门介绍
    30 --> 30S PT30S
    b spring-boot入门介绍

size的大小

  • 如果@DataSizeUnit没被设置,才会使用默认的
  • 更可度的方式,比如10MB

b spring-boot入门介绍
b spring-boot入门介绍

@ConfigurationProperties 校验

not null

b spring-boot入门介绍

@Valid

为了确保没有属性是,相关的属性必须被触发,所以必须加@Valid注解
b spring-boot入门介绍

@ConfigurationProperties 和 @Value比较

b spring-boot入门介绍