b spring-boot入门介绍
文章目录
- 4 Spring boot的特性
- 4.1 SpringApplication
- 4.1.1 Startup Failure 启动失败
- 4.1.2 懒加载
- 4.1.3 自定义 Banner
- 4.1.4 自定义 SpringApplication
- 4.1.5 流畅的builder API 定义SpringApplication
- 4.1.6 应用事件和监听。
- 4.1.7 Web Enviromment
- 4.1.8 启动参数的获取
- 4.1.9 使用Applicationer 或者CommandLineRunner
- 4.1.10 应用退出
- 4.1.1 Admin 特性
- 4.2 扩展配置
4 Spring boot的特性
这个章节对Spring boot有更细的介绍。如果你可想直接用,那么前面1~3已经可以满足你了,如果你想要自定义,必须得看下面细节得介绍。
4.1 SpringApplication
SpringApplication类提供了一个便方式来启动。
默认log的级别-- INFO
,这个可以设置请关注 Log levels
。
不过你可以使用利用实现
得方式来关闭启动信息的打印,通过设置spring.main.log-startup-info
为false
。
启动时你可以覆盖SpringApplication得子类得方法
logStartupInfo(boolean)
4.1.1 Startup Failure 启动失败
你的应用启动失败时,会注册FailureAnalyzers
类去提供一个描述失败信息的机会。
web引用的默认启动时8080,被占用时会报错
除了默认的你可以提供你自己的FailureAnalyzers
,怎么添加后面有介绍。
如果想要更详细得信息
方式一: 配置文件中设置debug级别
方式二:java -jar 设置 debugjava -jar myproject-0.0.1-SNAPSHOT.jar --debug
4.1.2 懒加载
懒加载开启后,类只有在被使用时加载,而非启动时。好处是节约启动时间。web项目时,懒加载会让http request命中时才会加载相关的bean。
由于懒加载,一些问题不能在启动时暴露,比如自身的问题,或者jvm内存不足得问题,所以默认懒加载时关闭的
打开懒加载
使用在SpringApplicationBuilder
的lazyInitialization
或者setLazyInitialization
方法。会这个使用初始化的属性来打开。
开一个注解@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
除此之外也可以用application.properties
来配置应用属性。
4.1.5 流畅的builder API 定义SpringApplication
如果你需要层次化得ApplicationContext,可以使用buildr模式,利用source
标记parent,child标记子方法
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
应用事件得发送顺序
-
ApplicationStartingEvent
产生在所有进程之前,除过listeners
和initializers
的注册。 - 在context被创建前,但Enviroment被确认后,
ApplicationEnvironmentPreparedEve
会发出 -
ApplicationContextInitializedEvent
被发出,当ApplicationContext
被准备好,ApplicationContextInitiallizers被调用,但是在任何bean 定义被加载前 -
ApplicationPrepareEvent
在context刷新之前发送,但是在bean 定义被加载之后 -
ApplicationStartedEvent
在context刷新之后,但是在应用和command-line runners被调用之前。 -
ApplicationReadyEvent
在任何application和commamd-line调用之后,意味着应用可以去正常服务 -
ApplicationFailedEvent
在启动存在异常时抛出。
上述列表只是在SpringApplication
中的SpringApplicationEvent
。
除了这些,还有下列的事件在ApplicationPreparedEvent
和ApplicationStartedEvent
被发送。
- ApplicationContext刷新时
ContextRefreshedEvent
被发送 -
WebServerInitializedEvent
被发送,在WebServver就绪时。ServletWebServerInitializedEvent
和ReactiveWebServerInitializedEvent
时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会默认被选中。
可以覆盖来选择
4.1.8 启动参数的获取
启动参数会被注入到org.springframework.boot.ApplicationArguments
bean。
可以解析命令和普通参数
4.1.9 使用Applicationer 或者CommandLineRunner
如果你要在SpringApplication启动后跑一些特殊的代码,一次性的。
可以实现ApplicationRunner
或者CommandLineRunner
接口,实现其Run方法。
ApplicationRunner
使用前面提到的ApplicationArguments
。CommandLineRunner
就是使用run加string参数
你可以实现org.springframework.core.Ordered
方法或者org.springframework.core.annotation.Order
来设定顺序
4.1.10 应用退出
每个SpringApplication会在在jvm注册一个shutdown hook。优雅的close时,所有的lifecycle会被调用,比如@PreDestory。
额外的你可以在退出时指定一个返回码
4.1.1 Admin 特性
你可以用spring.application.admin.enabled
属性来开启admin特性。它会在MBeanServer
暴露一个SpringApplicationAdminMXBean
。你可以使用这个特性来远程的管理的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值。具体如下
- 前面Devtools的全局设定,在
$HOME/.config/spring-boot
文件夹下。 - 你的test上使用
@TestPropertySource
注解 - 你tests上的
properties
注解,可以被@SpringBootTest
获得 - Commend line arguments
-
SPRING_APPLICATION_JSON
的Properties(在environment或者系统属性里内置的JSON) - ServletConfig 初始化参数
- ServletContext的初始化参数
- JNDI 属性在 java:comp/env
- java的系统属性
System.getProperties()
- OS的environment 变量
-
RandomValuePropertySource
只在random.*
- 在你packaged jar包之外的,profile application properties----application.{profile}.properties或者yaml
- 在你packaged jar包之内的,profile application properties----application.{profile}.properties或者yaml
- 在你packaged jar包和之外的其他application.properties或者yaml
- 在你packaged jar包和之内的其他application.properties或者yaml
- 你@Configuration注解上的
@PropertySource
。请注意这样的property sources 不会被添加到 Environment 直到应用的Context被刷新。所以这里配置logging.*
和spring.main.*
会太晚,他们在refresh 开始后 - SpringApplication的默认属性—SpringApplication.setDefaultProperties
示例Compent使用一个name属性
在application.properties
中加一个name就可以获得,测试时可以使用java -jar app.jar --name="Spring"
临时覆盖。
4.2.1 配置随机值
RandomValuePropertySource
在注入随机值时十分有用。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
文件里加载。
- 在当前目录下的
/config
- 当前目录
- classpath下的
/config
包 - class root
如果你不想用application.properties
作为配置文件的name或者想指定配置文件位置,可以如下
4.2.4 profile-具体的properties
application-{profile}.properties
可以靠spring.profiles.active
来设置。
4.2.5 占位符
application.properties中存在的值,会先放到Environment
中,所以你可以用占位符直接使用
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
。
这个属性会被加载成
被加载成
属性绑定
使用@ConfigurationProperties
来做属性绑定
把yml属性暴露在Spring Enviroment
YamlPropertiesSourceLoader
被用来把yaml作为一个PropertySource
。如果这么做了就可以使用@Value
的注解去访问yaml配置
多profile
你可以在一个文件里配置多个profile信息,需要使用spring.profiles
key。
需要属性的时候,如果都没有就会加载默认的,比如spring.security.user.password
只在default profile中配置。
其他可以不必配置
yaml的缺点
不能使用@PropertySource
注解来加载。
还有比如配置文件如下
当你使用--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后缀的属性全部绑定
其中嵌套类Security就被抓化为acme.security.username
propreties被映射到
@ConfigurationProperties类上,可以来源于properties,yaml files, environment等,但是get与setter并不会被使用
可以设默认值
Constructor binding
构造器绑定
注意@ConstructorBinding
注解,这个注解将会指示让构造器被调用
打开@ConfigurationProperties
注解
spring boot去绑定@ConfigurationProperties并注册为bean。
你可以依赖一般的ComponmentScan来扫描@ConfigurationProperties
。
有时被配置@ConfigurationProperties
并不会被扫描到,比如你自定义的starter。这是你可以在任何@Configuration
上打开@EnableConfigurationProperties
去详细指明properties的list,让他们被扫描
可以用sacn来指明需要扫描的未知,可以标记在任何类上。
我们推荐@Configuration
只用来处理environment,不要把context的其他bean注入进来。
使用@ConfigurationProperties-注解类型
假设
使用@ConfigurationProperties
被绑定并生成了AcmeProperties类
注入其他类中并使用
第三方配置
可以把@ConfigurationProperties
标记在@Bean
上,即bean定义的地方,可以用配置里的属性来初始化bean
松弛的绑定规则
spring使用宽松的绑定规则,不会那么精确,比如context-path
切换成contextPath
,或者PORT
和port
一致。
比如上面的这些例子里下面的这些值会被用到
对于不同的property source不用的源会被用到
复杂类型的合并
属性冲突时,没有profile被**,先到先得,被**时,被**的先命中。
Properties Conversion
属性转化,提供ConversionService
来对特定值转化成正常类型。
Converging durations 转换时间单位
时间单位的规范,以一种更可读的方式。java.time.Duration
属性,
- 一个long代表数字,如果
@DurationUnit
单位没被设置,才会采用默认的30S - ISO-8061格式
30 --> 30S PT30S
size的大小
- 如果
@DataSizeUnit
没被设置,才会使用默认的 - 更可度的方式,比如10MB
@ConfigurationProperties 校验
not null
@Valid
为了确保没有属性是,相关的属性必须被触发,所以必须加@Valid
注解