摘要:在创建之前,实际上触发了一些事件,因此不能将侦听器注册为。使用的事件发布机制发送应用程序事件,该机制的一部分确保在子环境中发布给侦听器的事件也会在任何祖先上下文中被发布给监听器。
23. SpringApplication
SpringApplication类提供了一种方便的方法来引导从main()方法开始的Spring应用程序。在许多情况下,你可以委托给静态SpringApplication.run方法,如下例所示:
public static void main(String[] args) { SpringApplication.run(MySpringConfiguration.class, args); }
当你的应用程序启动时,你应该看到类似于以下输出的内容:
. ____ _ __ _ _ / / ___"_ __ _ _(_)_ __ __ _ ( ( )\___ | "_ | "_| | "_ / _` | / ___)| |_)| | | | | || (_| | ) ) ) ) " |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: v2.0.5.RELEASE 2013-07-31 00:08:16.117 INFO 56603 --- [ Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb) 2013-07-31 00:08:16.166 INFO 56603 --- [main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext @6e5a8246:startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy 2014-03-04 13:09:54.912 INFO 41370 --- [main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080 2014-03-04 13:09:56.501 INFO 41370 --- [main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658)
默认情况下,显示INFO日志消息,包括一些相关的启动细节,比如启动应用程序的用户。如果你需要一个除INFO之外的日志级别,你可以设置它,如第26.4节所述,“日志级别”。
23.1 启动失败如果你的应用程序启动失败,注册的FailureAnalyzers将有机会提供专用的错误消息和解决问题的具体操作。例如,如果你在端口8080上启动web应用程序,并且该端口已经在使用,你应该会看到类似于以下消息的内容:
*************************** APPLICATION FAILED TO START *************************** Description: Embedded servlet container failed to start. Port 8080 was already in use. Action: Identify and stop the process that"s listening on port 8080 or configure this application to listen on another port.
Spring Boot提供了大量的FailureAnalyzer实现,你也可以添加自己的。
如果没有故障分析器能够处理的异常,你仍然可以显示完整的情况报告,以便更好地理解错误,要做到这一点,你需要为org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener启用debug属性或启用DEBUG日志记录。
例如,如果你正在使用java -jar运行你的应用程序,你可以使启用debug属性如下:
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug23.2 自定义横幅
在启动时打印的横幅可以通过添加banner.txt文件到你的类路径或设置spring.banner.location属性指向该文件的位置。如果文件的编码不是UTF-8,那么可以设置spring.banner.charset。除了一个文本文件,你还可以添加一个banner.gif、banner.jpg或banner.png图像文件到你的类路径或设置spring.banner.image.location属性。图像被转换成ASCII艺术表示,并打印在任何文本标题之上。
在你的banner.txt文件,你可以使用以下任何一个占位符:
表23.1. Banner变量
变量 | 描述 |
---|---|
${application.version} | 在MANIFEST.MF中声明的应用程序的版本号,例如,Implementation-Version:1.0被打印为1.0 |
${application.formatted-version} | 应用程序的版本号,如在MANIFEST.MF中声明并格式化以供显示(包含了括号和前缀v),例如(v1.0)) |
${spring-boot.version} | 你正在使用的Spring Boot版本,例如2.0.5.RELEASE |
${spring-boot.formatted-version} | 你正在使用的Spring Boot版本,格式化用于显示(用括号括起来,并以v为前缀),例如(v2.0.5.RELEASE) |
${Ansi.NAME}或${AnsiColor.NAME} | NAME是ANSI转义代码的名称,有关详细信息,请参阅AnsiPropertySource |
${application.title} | 你的应用程序的标题,如声明的那样,在MANIFEST.MF中,例如,Implementation-Title:MyApp被打印为MyApp) |
如果你想以编程的方式生成横幅,则可以使用SpringApplication.setBanner(…)方法,使用org.springframework.boot.Banner接口和实现你自己的printBanner()方法。
你也可以用spring.main.banner-mode属性确定横幅是否必须打印在系统上System.out(console),发送到已配置的日志记录器(log),或根本没有生成(off)。
在以下名称中,打印的横幅被注册为一个单例bean:springBootBanner。
YAML映射off到false,所以如果你想要禁用应用程序中的banner,请确保添加引号,如下例所示:
spring: main: banner-mode: "off"23.3 定制SpringApplication
如果SpringApplication的默认值不符合你的喜好,你可以创建一个本地实例并自定义它,例如,要关闭横幅,你可以写:
public static void main(String[] args) { SpringApplication app = new SpringApplication(MySpringConfiguration.class); app.setBannerMode(Banner.Mode.OFF); app.run(args); }
传递给SpringApplication的构造函数参数是Spring bean的配置源,在大多数情况下,这些都是对@Configuration类的引用,但是它们也可以是对XML配置的引用,或者对应该被扫描的包的引用。
还可以使用application.properties配置SpringApplication,详见第24节,外部化配置。
有关配置选项的完整列表,请参见SpringApplication Javadoc。
23.4 Fluent构建器API如果你需要构建ApplicationContext层次结构(包含parent和child关系的多个上下文),或者你更喜欢使用“fluent”构建器API,那么你可以使用SpringApplicationBuilder。
SpringApplicationBuilder允许你将多个方法调用链接在一起,并包含让你创建层次结构的父类和子方法,如下例所示:
new SpringApplicationBuilder() .sources(Parent.class) .child(Application.class) .bannerMode(Banner.Mode.OFF) .run(args);
在创建ApplicationContext层次结构时,有一些限制,例如,Web组件必须包含在子上下文内,并且在父类和子上下文环境中都使用相同的Environment,请参阅SpringApplicationBuilder Javadoc了解详细信息。23.5 应用程序事件和监听
除了通常的Spring框架事件,比如ContextRefreshedEvent之外,SpringApplication还会发送一些附加的应用程序事件。
在创建ApplicationContext之前,实际上触发了一些事件,因此不能将侦听器注册为@Bean。你可以使用SpringApplication.addListeners(...) 方法或SpringApplicationBuilder.listeners(...)方法注册它们。如果你希望这些监听器自动注册,不管应用程序是如何创建的,你都可以添加一个META-INF/spring.factories文件到你的项目,并通过使用org.springframework.context.ApplicationListener key来引用你的监听器,如下例所示:
org.springframework.context.ApplicationListener=com.example.project.MyListener
应用程序事件按以下顺序发送:
一个ApplicationStartingEvent是在运行开始时发送的,但是在任何处理之前,除了侦听器和初始化器的注册之外。
在创建上下文之前,当Environment在上下文中被使用时,就会发送一个ApplicationEnvironmentPreparedEvent。
一个ApplicationPreparedEvent是在刷新开始之前发送的,但是在加载了bean定义之后。
在调用上下文之后发送一个ApplicationStartedEvent,但是在调用任何应用程序和命令行运行程序之前。
在调用任何应用程序和命令行运行程序后,将发送一个ApplicationReadyEvent,它表明应用程序已经准备好服务请求。
如果启动时出现异常,则发送ApplicationFailedEvent。
你通常不需要使用应用程序事件,但是知道它们的存在是很方便的。在内部,Spring Boot使用事件来处理各种任务。
使用Spring Framework的事件发布机制发送应用程序事件,该机制的一部分确保在子环境中发布给侦听器的事件也会在任何祖先上下文中被发布给监听器。因此,如果你的应用程序使用了SpringApplication实例的层次结构,那么侦听器可能会接收到相同类型的应用程序事件的多个实例。
为了让你的侦听器区分事件的上下文和派生上下文的事件,它应该请求将其应用程序上下文注入,然后将注入的上下文与事件上下文进行比较,可以通过实现ApplicationContextAware或如果侦听器是bean,通过使用@Autowired来注入上下文。
23.6 Web环境SpringApplication试图为你创建合适的ApplicationContext类型,用于确定WebEnvironmentType的算法相当简单:
如果Spring MVC存在,则使用AnnotationConfigServletWebServerApplicationContext。
如果Spring MVC不存在,Spring WebFlux是存在的,那么就使用一个AnnotationConfigReactiveWebServerApplicationContext。
否则,AnnotationConfigApplicationContext被使用。
这意味着如果你使用Spring MVC和来自Spring WebFlux的新WebClient在相同的应用程序中,Spring MVC将在默认情况下使用,你可以通过调用setWebApplicationType(WebApplicationType)来轻松覆盖它。
还可以调用setApplicationContextClass(…)完全控制所使用的ApplicationContext类型。
在JUnit测试中使用SpringApplication时,通常需要调用setWebApplicationType(WebApplicationType.NONE)。23.7 访问应用程序参数
如果你需要访问传递给SpringApplication.run(…)的应用程序参数,你可以注入一个org.springframework.boot.ApplicationArguments bean,ApplicationArguments接口提供了对原始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"); Listfiles = args.getNonOptionArgs(); // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"] } }
Spring Boot还会在Spring Environment中注册一个CommandLinePropertySource,这允许你使用@Value注解注入单个应用程序参数。23.8 使用ApplicationRunner或CommandLineRunner
如果你需要在SpringApplication启动之后运行一些特定的代码,你可以实现ApplicationRunner或CommandLineRunner接口,两个接口都以相同的方式工作,并提供了一个多带带的run方法,在SpringApplication.run(…)完成之前调用。
CommandLineRunner接口提供对应用程序参数的访问作为一个简单的字符串数组,而ApplicationRunner使用前面讨论的ApplicationArguments接口。下面的示例展示了一个使用run方法的CommandLineRunner:
import org.springframework.boot.*; import org.springframework.stereotype.*; @Component public class MyBean implements CommandLineRunner { public void run(String... args) { // Do something... } }
如果定义了多个CommandLineRunner或ApplicationRunner bean,必须以特定的顺序调用它们,那么你可以额外地实现org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order注解。
23.9 应用程序退出每个SpringApplication都向JVM注册一个关闭hook以确保ApplicationContext在退出时优雅地关闭。可以使用所有标准的Spring生命周期回调函数(如DisposableBean接口或@PreDestroy注解)。
此外,当SpringApplication.exit()被调用时如果希望返回特定的退出代码则bean可以实现org.springframework.boot.ExitCodeGenerator接口。然后可以将此退出代码传递给System.exit(),以将其作为状态代码返回,如下面的示例所示:
@SpringBootApplication public class ExitCodeApplication { @Bean public ExitCodeGenerator exitCodeGenerator() { return () -> 42; } public static void main(String[] args) { System.exit(SpringApplication .exit(SpringApplication.run(ExitCodeApplication.class, args))); } }
此外,ExitCodeGenerator接口也可以由异常来实现,当遇到这样的异常时,Spring Boot返回由实现的getExitCode()方法提供的退出代码。
23.10 管理功能通过指定spring.application.admin.enabled属性可以为应用程序启用与admin相关的特性,这将在平台MBeanServer上公开SpringApplicationAdminMXBean,你可以使用该特性远程管理你的Spring Boot应用程序,这个特性还可以用于任何服务wrapper实现。
如果你想知道应用程序正在运行哪个HTTP端口,请使用local.server.port的键获取该属性。
在启用该特性时要注意,因为MBean公开了关闭应用程序的方法。上一篇:开发者工具 下一篇:外部化配置
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/69608.html
18. 使用@SpringBootApplication注解 许多Spring Boot开发人员喜欢他们的应用程序使用自动配置、组件扫描,并能够在他们的应用程序类上定义额外的配置,可以使用一个@SpringBootApplication注解来启用这三个特性: @EnableAutoConfiguration:启用Spring Boot的自动配置机制 @ComponentScan:在应用程序...
摘要:配置文件配置文件提供了一种方法来隔离应用程序配置的部分,并使其仅在某些环境中可用。特殊配置的配置文件或和通过引用的文件的特殊配置文件的变体被视为文件并被加载。 25. 配置文件 Spring配置文件提供了一种方法来隔离应用程序配置的部分,并使其仅在某些环境中可用。任何@Component或@Configuration都可以标记为@Profile,以限制加载时的限制,如下例所示: @Co...
摘要:开发你的第一个应用程序本节描述如何开发一个简单的应用程序来突出了的一些关键特性,我们使用来构建这个项目,因为大多数都支持它。如果你希望分发一个自包含的应用程序,这可能会有问题。 11. 开发你的第一个Spring Boot应用程序 本节描述如何开发一个简单的Hello World! web应用程序来突出了Spring Boot的一些关键特性,我们使用Maven来构建这个项目,因为大多数...
摘要:系列文章更新计划列表主要对一些中常用的框架进行简单的介绍及快速上手,外加相关资料的收集更新列表会不定期的加入新的内容以进行扩充,如果你对此感兴趣可以站内联系我。 导读: 从第一次接触Spring Boot 至今已经有半年多了,在这期间也浏览了许多和Spring Boot 相关的书籍及文章,公司里面的许多项目也一直在使用Spring Boot。关于Spring Boot的一些看法:Spr...
摘要:结构化你的代码不需要任何特定的代码布局来工作,然而有一些最佳实践可以提供帮助。我们建议你遵循推荐的包命名约定和使用反向域名例如,。 14. 结构化你的代码 Spring Boot不需要任何特定的代码布局来工作,然而有一些最佳实践可以提供帮助。 14.1 使用default包 当一个类不包含package声明时,它被认为是在default package中,使用default packa...
阅读 1863·2023-04-26 02:46
阅读 1994·2021-11-25 09:43
阅读 1139·2021-09-29 09:35
阅读 2094·2019-08-30 15:56
阅读 3417·2019-08-30 15:54
阅读 2626·2019-08-29 16:35
阅读 3115·2019-08-29 15:25
阅读 3281·2019-08-29 14:01