Spring Boot 官方文档学习特点
Posted 官小飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,以下面的顺序发送:
ApplicationStartedEvent 应用启动时发送,是除了注册监听器和初始化之外最早的。
ApplicationEnvironmentPreparedEvent 创建context之前,已知道context需要使用的Environment时。
ApplicationPreparedEvent 发生在context刷新之前,但在bean 定义加载之后。
ApplicationReadyEvent 发生在刷新和任何相关回调被处理之后,表明应用已准备好响应请求了。
ApplicationFailedEvent 发生在启动期间发生异常时。
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下的优先级比默认的高。具体如下:@TestPropertySource annotations on your tests.
Command line arguments.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
Java System properties (System.getProperties()).
OS environment variables.
A RandomValuePropertySource that only has properties in random.*.
Profile-specific application properties outside of your packaged jar (application-profile.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).
Application properties packaged inside your jar (application.properties and YAML variants).
@PropertySource annotations on your @Configuration classes.
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.
app.name=MyApp
app.description=$app.name is a Spring Boot application
@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.active
Environment
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.xml , logback-spring.groovy , logback.xml or logback.groovy |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) | logging.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). |
<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。
以上是关于Spring Boot 官方文档学习特点的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 2从入门到入坟 | 基础入门篇:你会看Spring Boot的官方文档吗?