[Spring Boot 系列教程] SpringBootApplication

  • [Spring Boot 系列教程] 目录
  • 源码(demo03)

在上一篇文章中,我们介绍了 Spring Boot 提供的 DevTools,在本篇文章中,将介绍 SpringApplication 这个类。

在之前的文章中,我们知道了 SpringApplicationSpring Boot 应用的入口,在本文中,将深入介绍 SpringApplication 的一些其它特性。

运行应用

SpringApplication 提供了一个静态方法(run),使得我们可以通过 main 方法来启动 Spring 应用程序。如下所示:

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

当应用启动成功后,你应该看到以下的内容:

.   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/  ___)| |_)| | | | | || (_| |  ) ) ) )
'  |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot ::   v2.1.0.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] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.ser[emailprotected]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 级别的日志,并输出一些启动相关的消息,如:应用端口、程序 PID,启动程序的用户等。如果你希望看到更详细的信息,可以通过外部配置的方式,指定以 debug 模式启动应用,或是直接通过修改系统日志的配置,来显示更为详细的信息。

启动失败分析器

当你的应用启动失败时,你通常会得到类似下面的错误提示:

***************************
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 提供的 FailureAnalyzers 来展示给我们的,它能让我们更加清楚的知道应用为什么会无法启动,如上面给的提示,非常明确的告诉我们 8080 的端口已经被占用,导致了程序无法启动。

SPring Boot 已经内置了常见的一些 FailureAnalyzers,如果这些无法满足你项目的需求,你也可以自己实现它。

当然,如果没有任何 FailureAnalyzers 能够处理启动异常,你也可以通过其他途径来获取详细的异常堆栈信息:

  • 使用 debug 模式启动应用
  • 将日志设置为 debug 级别

例如,如果你使用的是 java -jar 的方式启动的应用,则可以按照以下方式启用 debug 模式:

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

自定义 Banner

这是个非常好玩的功能,Banner 指的就是当系统启动时,最开始打印的内容,如:

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

以上的内容,我们可以自行定义。我们只需要在项目 classpath 下添加 banner.txt ,并在里面输入 banner 的内容即可,默认情况下,banner.txt 将会使用 UTF-8 编码解析,如果你需要制定编码,可以设置 banner.charset 属性。下表列出了在 banner.txt 中支持的变量:

Variable Description
${application.version} The version number of your application as declared in MANIFEST.MF. For exampleImplementation-Version: 1.0 is printed as 1.0.
${application.formatted-version} The version number of your application as declared in MANIFEST.MF formatted for display (surrounded with brackets and prefixed with v). For example (v1.0).
${spring-boot.version} The Spring Boot version that you are using. For example 1.5.19.RELEASE.
${spring-boot.formatted-version} The Spring Boot version that you are using formatted for display (surrounded with brackets and prefixed with v). For example (v1.5.19.RELEASE).
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) Where NAME is the name of an ANSI escape code. See AnsiPropertySource for details.
${application.title} The title of your application as declared in MANIFEST.MF. For exampleImplementation-Title: MyApp is printed as MyApp.

最强大的是,banner 不仅支持文字,它还可以支持 .git.jpg 格式的图像,只需要设置 banner.image.location 属性即可,有兴趣的可以自己去实验。

如果你想禁用 banner,也非常简单,可以通过以下方式:

  • 通过配置文件指定
spring:
    main:
        banner-mode: "off"
  • 通过编程方式指定
public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}

自定义 SpringApplication

如果默认设置不满足你的需求,你也可以自行定义它。自定义 SpringApplication 有两种方式,第一就是传统的方式,设置类的属性值,如上面设置 banner mode;还有一种方式是使用 Builder 模式进行设置,如:

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

应用事件及其监听

SpringApplication 在启动、运行和关闭的时候,将会注册一系列的事件供我们去订阅。

这里有一点需要注意的是,因为某些事件是在 ApplicationContext 创建之前就被触发的,所以不能将它们注册为 @Bean,只能通过 SpringApplication.addListeners(…)SpringApplicationBuilder.listeners(…) 的方式去注册它,如果你希望它们被自动注册,你也可以在应用 classpath 下面添加 META-INF/spring.factories 文件,并在启动添加以下内容:

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

以下是当你应用运行时,一些事件的发生顺序:

  1. ApplicationStartingEvent
  2. ApplicationEnvironmentPreparedEvent
  3. ApplicationPreparedEvent
  4. ApplicationReadyEvent
  5. ApplicationFailedEvent

Web 环境

Spring Boot 应用会尝试去创建正确的应用程序上下文。默认情况下,AnnotationConfigApplicationContext 或是 AnnotationConfigEmbeddedWebApplicationContext将被创建,具体创建哪一个上下文基于你开发的是否是一个 Web 程序。当然,你也可以通过编程方式去指定它:setWebEnvironment(boolean webEnvironment)

获取应用的参数

当你需要从命令行或是其它方式指定应用的参数时,你可以通过以下方式去获取这些参数:

**通过 ApplicationArguments **

ApplicationArguments 接口提供了一些方法让我们非常方便的访问应用的参数:

public interface ApplicationArguments {

	String[] getSourceArgs();

	Set<String> getOptionNames();

	boolean containsOption(String name);

	List<String> getOptionValues(String name);

	List<String> getNonOptionArgs();
}

如:

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"]
    }

}

通过 @Value 注解

Spring Boot 将会把应用参数注册为 CommandLinePropertySource ,这就使得我们可以通过 @Value 注解方式去访问这些参数。

使用 ApplicationRunner 或是 CommandLineRunner

如果你需要在程序启动时运行某些特殊的代码,你可以实现 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...
    }

}

应用退出

每一个 SpringApplication 都将注册一个关闭钩子,用于确保应用被优雅的关闭。

Admin 特性

结语

本文介绍了 SpringApplication 这个类的一些特性,在下一篇文章中,将介绍 Spring Boot 应用的外部配置。

你可能感兴趣的:(Spring,Boot,系列教程)