SprigApplication

本文介绍了启动Spring应用的方式,包括启动顺序、启动失败处理。还阐述了定制SpringApplication的方法,如使用set方法或builder方式。同时讲解了应用事件和监听机制、推断网络环境、应用参数操作、ApplicationRunner或CommandLineRunner的使用,以及应用退出时的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方文档地址
提供一种方便的启动spring应用的方式
使用run()方法用来启动Spring应用,即创建一个Spring上下文(返回值)
SpringApplication.run(MyApplication.class,args)其中MyApplication.class必须是加了@SpringBootApplicationConfiguration注解的类,args为启动时的命令行参数。main方法的类是java程序的入口类,在这个入口类中启动了Spring应用。下面的例子是在内部类中使用了@SpringBootApplication,注意内部类初始化需要外部类的实例,所以需要声明为static

public class AjaxApplication {
    public static void main(String[] args) {
        SpringApplication.run(Test.class,args);
    }
    @SpringBootApplication
    public static class Test{

    }
}

启动顺序

  1. 创建一个应用上下文实例
  2. 注册CommandLinePropertySource将命令行参数转化为Spring属性
  3. 刷新应用上下文,载入所有单例bean
  4. 触发所有CommandLineRunner bean

启动失败

FailureAnalyzers能够可能为你提供一份详细的错误报告和解决方法,可以实现FailureAnalyzer来定制

定制SpringApplication

默认SpringApplication无法满足要求时可以自己定制,直接new SpringApplication(MySpringConfiguration.class)并使用各种set方法进行定制化,或者使用其builder方式SpringApplicationBuilder使代码更简洁且可以垂直的使用其子类和父类的方法进行定制;

应用事件(Events)和监听(Listeners)

有些Event的触发是在SpringApplication创建之前的,因此这部分事件无法声明为bean去起作用,需要在SpringApplication创建时去手动添加监听器,或者在META-INF/spring.factories文件中配置监听器,并以org.springframework.context.ApplicationListener为key
应用事件的发生顺序如下:

  1. ApplicationStartingEvent在run时但未进行任何操作之前(除非监听器的注册和初始化)
  2. ApplicationEnvironmentPreparedEvent确定应用上下文使用的Environment且上下文创建之前
  3. ApplicationPreparedEvent定义的bean被装载之后但在应用上下文refresh之前
  4. ApplicationStartedEvent应用上下文刷新后但在所有应用和command-line回调之前
  5. ApplicationReadyEvent所有应用和command-line线程已经完成调用,标志着应用已经准备好服务请求
  6. ApplicationFailedEvent启动时抛出异常时

应用事件的发送采用spring发布模式,子上下文的事件监听器也会发布到父上下文,因此如果应用采用垂直SpringApplication实例,一个监听器可能会受到许多相同应用事件类型的实例。为了区分监听器来自哪个应用上下文,context应该可以被注入并与事件上下文做比较。context注入可以采用ApplicationContextAware或者当监听器是一个bean时可以使用@Autowired

推断网络环境

  • 如果存在类org.springframework.web.reactive.DispatcherHandler且不存在类org.springframework.web.servlet.DispatcherServlet则使用AnnotationConfigReactiveWebServerApplicationContext
  • 当不存在org.springframework.web.servlet.DispatcherServletjavax.servlet.Servlet时将设置为AnnotationConfigApplicationContext
  • 当存在SpringMVC时为AnnotationConfigServletWebServerApplicationContext
  • 可以在SpringApplication中设置网络环境
static WebApplicationType deduceFromClasspath() {
        if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
            return REACTIVE;
        } else {
            String[] var0 = SERVLET_INDICATOR_CLASSES;
            int var1 = var0.length;
            for(int var2 = 0; var2 < var1; ++var2) {
                String className = var0[var2];
                if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
                    return NONE;
                }
            }
            return SERVLET;
        }
    }

应用参数

ApplicationArguments来操作run()方法中的参数

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 or CommandLineRunner

SpringApplication启动后运行一次个性化代码,可以实现ApplicationRunner或者 CommandLineRunner接口,只有一个run方法在SpringApplication.run(…​)完成之前被调用
CommandLineRunner提供访问应用参数作为一个简单的String数组,代码如下:

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

@Component
public class MyBean implements CommandLineRunner {

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

}

可以实现org.springframework.core.Ordered接口来定义执行顺序
ApplicationRunner使用参数ApplicationArguments

应用退出

每个SpringApplication都在JVM上注册有一个关闭的钩子来保证优雅的关闭,从而有时间能够调用相关回调函数(如DisposableBean接口 或 @PreDestroy 注解表示的方法)
beans可以实现org.springframework.boot.ExitCodeGenerator来自定义exit code并可以将之传递到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)));
	}

}

getExitCode()之处抛出异常时返回的exit code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值