Spring Applications
SpringApplication: 提供一种便携的方式来启动Spring应用(main函数)。 可以使用静态方法调用 SpringApplication.run
启动
启动日志
- Spring启动日志默认为info级别,可以关闭 spring.main.log-startup-info=false
- FailureAnalyzers 处理启动时抛出的异常,可以自己实现
- 若仍无analyzer处理异常,则可以使用DEBUG级别的日志,或者启动时增加debug属性:
- JAVA -jar *.jar --debug
延迟加载
- 延迟加载默认关闭,开启有可能导致错误延后发现
- 延迟加载开关配置: spring.main.lazy-initialzation=true
- 延迟开关代码: SpringApplicationBuilder lazyInitialization; SpringApplication setLazyInitialization
- 延迟开关注解: @Lazy(false)
banner
- 类: SpringBootBanner
- 配置文件 banner.txt
- 支持将系统的一些变量输出
- 代码设置: SpringApplication.setBanner()
- 开关配置 console/log/off: spring.main.banner-mode=off
- 地址配置:spring.banner.location
自定义Spring Application
- 支持自定义SpringApplication
- @SpringBootApplication
public class MyApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(MyApplication.class); application.setBannerMode(Banner.Mode.OFF); application.run(args); }}
Builder API
- Springboot应用构建
- new SpringApplicationBuilder()
.sources(Parent.class) .child(Application.class) .bannerMode(Banner.Mode.OFF) .run(args);
应用可用性监控
- Spring boot actuator
- ApplicationAvailability 实现该接口来向外暴露状态
Liveness State
应用是否存活,与外部状态无关
Readiness State
应用是否可用(例如CommandLineRunner ApplicationRunner在被执行时)
状态管理
- 监听状态改变
- @Component
public class MyReadinessStateExporter { @EventListener public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) { switch (event.getState()) { case ACCEPTING_TRAFFIC: // create file /tmp/healthy break; case REFUSING_TRAFFIC: // remove file /tmp/healthy break; } }}
- 改变状态
- @Component
public class MyLocalCacheVerifier { private final ApplicationEventPublisher eventPublisher; public MyLocalCacheVerifier(ApplicationEventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void checkLocalCache() { try { // ... } catch (CacheCompletelyBrokenException ex) { AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN); } }}
应用事件监听
除了通常的Spring事件, 比如ContextRefreshedEvent, SpringApplication还可以发送其他事件
有些事件在ApplicationContext创建之前触发,这种无法通过注册bean来注册监听器,可以通过其他方式监听:
SpringApplication.addListeners()/ SpringApplication.listeners()
支持自动化配置listeners. META_INF/spring.factories
org.springframework.context.ApplicationListener=com.example.MyListener
应用实践发送顺序:
- An ApplicationStartingEvent is sent at the start of a run but before any processing, except for the registration of listeners and initializers.
- An ApplicationEnvironmentPreparedEvent is sent when the Environment to be used in the context is known but before the context is created.
- An ApplicationContextInitializedEvent is sent when the ApplicationContext is prepared and ApplicationContextInitializers have been called but before any bean definitions are loaded.
- An ApplicationPreparedEvent is sent just before the refresh is started but after bean definitions have been loaded.
- An ApplicationStartedEvent is sent after the context has been refreshed but before any application and command-line runners have been called.
- An AvailabilityChangeEvent is sent right after with LivenessState.CORRECT to indicate that the application is considered as live.
- An ApplicationReadyEvent is sent after any application and command-line runners have been called.
- An AvailabilityChangeEvent is sent right after with ReadinessState.ACCEPTING_TRAFFIC to indicate that the application is ready to service requests.
- An ApplicationFailedEvent is sent if there is an exception on startup.
当ApplicationContext 被刷新后会触发ContextRefreshedEvent
实现ApplicationContextAware 可注入ApplicationContext
获取启动参数
ApplicationArguments
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
ApplicationRunner CommandLineRunner
在SpringApplication启动之后, 需要运行相关代码时, 可以用ApplicationRunner或CommandLineRunner。 接口均实现run方法。 区别是ApplicationRunner使用ApplicationArguments, CommandLineRunner使用字符串数组接收请求参数。
若有多个bean被定义并要求有顺序执行,可以实现
org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order
应用关闭
每个Spring应用会向JVM注册一个钩子确保ApplicationContext可以顺利关闭 每个标准Spring生命周期的方法会被调用(例如DisposableBean 或@PreDestroy)
可以指定错误码
org.springframework.boot.ExitCodeGenerator(自定义异常错误码)
SpringApplicaiton.exit()
管理特性
启动管理功能,支持远程管理,暴露
SpringApplicationAdminMXBean MBeanServer
spring.application.admin.enabled=true
外部配置
包含Java properties files, yaml files, environment variables, command-line arguments
可通过@Value获取 或者 结构化对象(通过@ConfigurationProperties)
@value(${name:123})
配置优先级
- Default properties (specified by setting SpringApplication.setDefaultProperties).
- @PropertySource annotations on your @Configuration classes. Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.
- Config data (such as application.properties files).
- A RandomValuePropertySource that has properties only in random.*.
- OS environment variables.
- Java System properties (System.getProperties()).
- JNDI attributes from java:comp/env.
- ServletContext init parameters.
- ServletConfig init parameters.
- Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property).
- Command line arguments.
- properties attribute on your tests. Available on @SpringBootTest and the test annotations for testing a particular slice of your application.
- @TestPropertySource annotations on your tests.
- Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.
配置文件按以下优先级覆盖
- Application properties packaged inside your jar (application.properties and YAML variants).
- Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
- Application properties outside of your packaged jar (application.properties and YAML variants).
- Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
可通过命令行设置配置
使用 -- 前缀
关闭命令行参数
SpringApplication.setAddCommandLineProperties(false)
通过json配置
环境变量: SPRING_APPLICATION_JSON java 启动命令: -Dspring.application.json
外部配置
通过以下顺序:
- classpath
- classpath
- classpath/config
- current dir
- current dir
- current dir/config
修改配置文件名称 Java启动命令 --spring.config.name=···
修改配置文件地址 --spring.config.location
--spring.config.additional-location
配置文件地址支持使用通配符* , 支持多个目录配置文件
环境配置文件 application-{profile}
外部导入
支持外部导入配置文件
spring.config.import=optional:file:./dev.properties
若不支持后缀名可以换写法:
spring.config.import=optional:file:./dev[.ymal]
配置树
可支持按文件层级关系做配置
spring.config.import=optional:configtree:/etc/config
占位符
可使用其他配置作为变量 ${app.name}
配置中的随机变量
支持integer, long, uuid, strings.
${random.value}
${random.int}
${random.long}
${random.uuid}
${random.int(10)}
${random.int[1024, 65536]}
类型安全的配置(使用类配置)
@ConfigurationProperties("") 注意还需要作为一个bean来注入使用
Profiles
任何@Comp.NET, @Configuration, @ConfigurationProperties都可以被@Profile限制。
指定激活profile
spring.profiles.active=dev,hsqldb
spring.profiles.default=none
profile group
profiles
spring.profiles.group.production[0]=proddb
spring.profiles.group.production[1]=prodmq
程序设置profile
SpringApplication.setAdditionalProfiles(...)
Logging
日志格式
- Date and Time: Millisecond precision and easily sortable.
- Log Level: ERROR, WARN, INFO, DEBUG, or TRACE.
- Process ID.
- A --- separator to distinguish the start of actual log messages.
- Thread name: Enclosed in square brackets (may be truncated for console output).
- Logger name: This is usually the source class name (often abbreviated).
- The log message.
日志颜色
%clr 来指定日志颜色
%clr(%5p)
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
颜色支持: blue,cyan,faint,green,magenta,red,yellow
文件输出
日志文件为10MB, 默认输出ERROR, WARN, INFO logging.file.name logging.file.path
file rotation
- logging.logback.rollingpolicy.file-name-pattern
- The filename pattern used to create log archives.
- logging.logback.rollingpolicy.clean-history-on-start
- If log archive cleanup should occur when the application starts.
- logging.logback.rollingpolicy.max-file-size
- The maximum size of log file before it is archived.
- logging.logback.rollingpolicy.total-size-cap
- The maximum amount of size log archives can take before being deleted.
- logging.logback.rollingpolicy.max-history
- The maximum number of archive log files to keep (defaults to 7).
日志等级
日志级别: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
logging.level.<logger-name>=<level>
logging.level.root=
日志组
spring有预设的日志组 如 web, sql
logging.group.Tomcat=org.Apache.catalina,org.apache.coyote,org.apache.tomcat
logging.level.tomcat=trace
日志关闭钩子
logging.register-shutdown-hook=false
自定义日志配置
指定自定义日志系统
org.springframework.boot.logging.LoggingSystem=
logback: logback-spring.xml, logback.xml
log4j2: log4j2-spring.xml, log4j2.xml
JDK: logging.properties