Spring Boot官方文档 - SpringApplication


SpringApplication提供了一个便捷方式帮助Spring应用从main()方法启动。在很多场景中你可以只托管给静态的SpringApplication.run方法:

public static void main(String[] args) {
    SpringApplication.run(MySpringConfiguration.class, args);
}

应用启动后应该会有类似以下的输出:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v1.5.6.RELEASE

2013-07-31 00:08:16.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : 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] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@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.TomcatEmbeddedServletContainerFactory : 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级别的日志信息,包括一些相关的启动细节,如启动应用程序的用户。

启动失败

如果应用启动失败,注册的FailureAnalyzers有机会提供专门的错误消息和具体的措施来解决问题。例如,如果在8080端口启动web应用,而8080端口已经被占用了,你应该会看到以下类似的输出信息:

***************************
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.

如果没有错误分析器处理异常,您仍然可以显示完整的自动配置报告,以更好地了解出现的问题。要做到这个效果,你需要启用org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer的debug属性或debug日志。

例如,如果你使用java -jar运行应用,你可以通过以下方式启用debug属性:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

定制Banner

启动时打印的banner可以通过在classpath下添加banner.txt来修改,或者通过指定banner.location设置文件。如果这个文件是不寻常编码,你可以设置banner.charset(默认UTF-8)。除了添加文本文件以外,你还可以在classpath下添加banner.gif、banner.jpg或banner.png,或者通过设置banner.image.location属性。图像将被转换成ASCII艺术形式,覆盖所有文本的形式并打印出来。

你可以在banner.txt里使用以下的占位符:

变量 描述
${application.version} 定义在MANIFEST.MF里的应用版本号。
${application.formatted-version} 定义在MANIFEST.MF里的应用版本号显示格式,如v1.0。
${spring-boot.version} 当前正在使用的Spring Boot版本号。如1.5.6.RELEASE。
${spring-boot.formatted-version} 当前正在使用的Spring Boot版本号展示格式。如v1.5.6.RELEASE。
${Ansi.NAME} (or ${AnsiColor.NAME},${AnsiBackground.NAME}, ${AnsiStyle.NAME}) ANSI转义码名字。
${application.title} 定义在MANIFEST.MF里的应用标题。

注:如果你想编程实现banner,可以使用org.springframework.boot.Banner接口实现自己的printBanner()方法。再通过SpringApplication.setBanner(...)方法设置。

你还可以使用spring.main.banner-mode属性来定义是在System.out(console)上打印、使用配置的logger(log)或不打印(off)。

定制SpringApplication

如果默认的SpringApplication不能满足你的需求,你可以创建一个本地实例并定制它。例如,关闭banner:

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

SpringApplication的构造函数是spring beans配置源。在大多数情况下,它们会引用@Configuration类,但也可以引用XML配置或扫描包。

当然还可以使用application.properties来配置SpringApplication,这个以后的章节中会讲到。

链式构造器API

如果你需要构造一个ApplicationContext层次结构,或者你只是体验"链式"构造器API,你可以使用SpringApplicationBuilder。

SpringApplicationBuilder可让你链式调用多个方法,还包括 parent和child方法可让你创建一个层次结构。

例如:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);

Application events and listeners(事件和监听器)

除了常见的Spring Framework事件,如ContextRefreshedEvent,SpringApplication还会触发一些其他事件。

注:有一些事件是在创建ApplicationContext之前触发的,所以在注册这些事件时不能使用@Bean。你可以通过SpringApplication.addListeners或SpringApplicationBuilder.listeners方法注册。

如果你想自动注册这些监听,而不管如何创建应用。你可以添加一个META-INF/spring.factories文件,使用org.springframework.contentext.ApplicationListener引用你的Listener。如:

org.springframework.context.ApplicationListener=com.example.project.MyListener

  • ApplicationStartingEvent:开始启动,但在除了注册监听器和初始化程序之外的任何处理之前。
  • ApplicationEnvironmentPreparedEvent:context中已经装配Environment,且在创建context完成之前。
  • ApplicationPreparedEvent:启动刷新之前,但在加载Bean之后。
  • ApplicationReadyEvent:所有相关callback处理完成和刷新之后,应用准备好提供服务,
  • ApplicationFailedEvent:启动时发生异常。

你通常不需要使用应用事件,但了解他们会更方便。在内部,Spring Boot使用事件处理各种任务。

Web environment(Web环境)

SpringApplication会尝试创建正确的ApplicationContext。默认情况下,会根据你开发的应用类型是否是web应用,来使用AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext。

确定"web environment"的算法非常简单(根据一些类的存在)。如果你需要覆盖默认的算法,你可以使用setWebEnvironment(boolean webEnvironment)设置。

也可以通过调用setApplicationContextClass()来完全控制ApplicationContext的类型。

注:在JUnit测试中使用SpringApplication时,通常需要调用setWebEnvironment(false)。

访问应用参数

如果你要访问传入到SpringApplication.run()里的应用参数,你可以注入org.springframework.boot.ApplicationArguments。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");
        List<String> files = args.getNonOptionArgs();
        // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
    }

}

使用ApplicationRunner或CommandLineRunner

如果你想在SpringApplication启动后运行一些特殊代码,你可以实现ApplicationRunner或CommandLineRunner接口。这两个接口都提供了一个run方法,这个会在SpringApplication.run()完成之前调用。

CommandLineRunner接口提供以字符串数组的形式访问应用参数,而ApplicationRunner使用上述的ApplicationArguments。

import org.springframework.boot.*
import org.springframework.stereotype.*

@Component
public class MyBean implements CommandLineRunner {

    public void run(String... args) {
        // Do something...
    }

}

如果你定义了多个CommandLineRunner或ApplicationRunner,并必须按照特定顺序执行。你可以通过实现org.springframework.core.Ordered接口或使用org.springframework.core.annotation.Order注解实现。

Application exit(应用退出)

每个SpringApplication都会注册一个JVM的shutdown hook(关闭钩子),以确保在退出的时候正常关闭ApplicationContext。可以使用所有标准的Spring生命周期回调。

此外,如果想在SpringApplication.exit()调用时返回特殊的退出码,可以实现org.springframework.boot.ExitCodeGenerator接口。然后可以将此退出码传递给System.exit()作为状态代码返回。

@SpringBootApplication
public class ExitCodeApplication {

	@Bean
	public ExitCodeGenerator exitCodeGenerator() {
		return new ExitCodeGenerator() {
			@Override
			public int getExitCode() {
				return 42;
			}
		};
	}

	public static void main(String[] args) {
		System.exit(SpringApplication
				.exit(SpringApplication.run(ExitCodeApplication.class, args)));
	}

}

此外,ExitCodeGenerator接口还可以由异常来实现。遇到这样的异常时,Spring Boot会返回实现的getExitCode()方法的退出码。

管理员特性

设置spring.application.admin.enabled属性可以启用管理员相关特性。将SpringApplicationAdminMXBean暴漏在MBeanServer平台上。可以通过这个特性远程管理Spring Boot应用。这对于任何服务包装器实现都是有用的。

注意;启用这个功能的时候请小心,因为MBean公开了关闭应用程序的方法。

 

马军伟
关于作者 马军伟
写的不错,支持一下

先给自己定个小目标,日更一新。