定义:Spring应用引导类,提供便利的自定义行为方法。
SpringApplication 运行3种
@SpringBootApplication
public class ApplicationNewDemo {
public static void main(String[] args) {
SpringApplication.run(ApplicationNewDemo .class, args);
}
public static void main(String[] args) {
Set<String> sources = new HashSet<>();
sources.add(MyApplication.class.getName());
SpringApplication application = new SpringApplication();
application.setSources(sources);//添加bean
//REACTIVE和SERVLET都有时会使用SERVLET
application.setWebApplicationType(WebApplicationType.SERVLET);
application.setAdditionalProfiles("Cat","Dog");//添加profile
ConfigurableApplicationContext context = application.run(args);
System.out.println("bean: " + context.getBean(MyApplication.class));
}
@SpringBootApplication
public static class MyApplication{ }
@SpringBootApplication
public class ApplicationBuilderDemo {
public static void main(String[] args) {
new SpringApplicationBuilder(ApplicationBuilderDemo.class)
.bannerMode(Banner.Mode.CONSOLE)
.web(WebApplicationType.NONE)
.profiles("Cat","Dog")
.headless(true)
.run(args);
}
}
推断
web模式推断:Servlet、Reactive同时存在使用Servlet,只存在一个使用存在的(通过实现类是否存在判断:Reactive -》DispatcherHandler,Reactive -》DispatcherServlet)
推断引导类:通过堆栈classpath查找使用main作为方法名的方法。
配置上下文初始化器
这个时候是bean加载之前,只能做一些初始化操作
通过order实现加载顺序(值是int类型,越大优先级越小),2种方法(@order/实现order接口)效果一样
@Order(Ordered.HIGHEST_PRECEDENCE)
public class OneApplicationContextInitializer<C extends ConfigurableApplicationContext>
implements ApplicationContextInitializer<C> {
@Override
public void initialize(C applicationContext) {
System.out.println("One ApplicationContext.id = "+ applicationContext.getId());
}
}
public class TwoApplicationContextInitializer implements ApplicationContextInitializer, Ordered {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("Two application.id = " + applicationContext.getId());
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
META-INF.spring.factories
# ApplicationContextInitializer 实现配置
org.springframework.context.ApplicationContextInitializer=\
com.stude.gray.spring_boot.application.context.TwoApplicationContextInitializer,\
com.stude.gray.spring_boot.application.context.OneApplicationContextInitializer
添加事件监听 ApplicationListener
模拟监听上下文完成事件
public class HelloWorldApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
System.out.println("HelloWorld : " + event.getApplicationContext().getId()
+ " , timestamp : " + event.getTimestamp());
}
}
META-INF.spring.factories
# ApplicationListener 实现配置
org.springframework.context.ApplicationListener=\
com.stude.gray.spring_boot.application.listener.HelloWorldApplicationListener
在上下文中注册监听器,并发布监听事件
public static void main(String[] args) {
// 创建上下文(none)
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//创建上下文(Servlet)
//AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext();
//创建上下文(Reactive)
// AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext();
// 注册应用事件监听器
context.addApplicationListener(event -> {
System.out.println("监听到事件: " + event);
});
// 启动上下文
context.refresh();
// 发送事件
context.publishEvent("HelloWorld");
context.publishEvent("2018");
context.publishEvent(new ApplicationEvent("小马哥") {
});
// 关闭上下文
context.close();
}
添加运行时监听器SpringApplicationRunListener
public class HelloWorldRunListener implements SpringApplicationRunListener {
//必须要有这个构造器
public HelloWorldRunListener(SpringApplication application, String[] args) {
}
@Override
public void starting() {
System.out.println("HelloWorldRunListener.starting()...");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
}
@Override
public void started(ConfigurableApplicationContext context) {
}
@Override
public void running(ConfigurableApplicationContext context) {
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
}
}
META-INF.spring.factories
org.springframework.boot.SpringApplicationRunListener=\
com.stude.gray.spring_boot.application.listener.HelloWorldRunListener
各监听阶段说明
监听方法 | 执行位置 | 监听事件 |
---|---|---|
starting() | Spring 应用刚启动 | ApplicationStartingEvent |
environmentPrepared(ConfigurableEnvironment) | ConfigurableEnvironment 准备妥当,允许将其调整 | ApplicationEnvironmentPreparedEvent |
contextPrepared(ConfigurableApplicationContext) | ConfigurableApplicationContext 准备妥当,允许将其调整 | |
contextLoaded(ConfigurableApplicationContext) | ConfigurableApplicationContext 已装载,但仍未启动 | ApplicationPreparedEvent |
started(ConfigurableApplicationContext) | ConfigurableApplicationContext 已启动,此时 Spring Bean 已初始化完成 | ApplicationStartedEvent |
running(ConfigurableApplicationContext) | Spring 应用正在运行 | ApplicationReadyEvent |
failed(ConfigurableApplicationContext,Throwable) | Spring 应用运行失败 | ApplicationFailedEvent |
启动完成回调接口
二者基本一样,区别在于接收的参数不一样。CommandLineRunner的参数是最原始的参数,没有做任何处理,而ApplicationRunner的参数是ApplicationArguments,对原始参数做了进一步的封装。
@Component
public class ServerStartedReport implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
for(String ars : args){
System.out.println(ars);
}
System.out.println("===========CommandLineRunner启动====="+ LocalDateTime.now());
}
}
@Component
public class MyApplicationRunner implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("ApplicationRunner:"+ Arrays.asList(args.getSourceArgs()));
System.out.println("getOptionNames:"+args.getOptionNames());
System.out.println("getOptionValues:"+args.getOptionValues("foo"));
System.out.println("getOptionValues:"+args.getOptionValues("log"));
}
}
关闭上下文
@RestController
public class Hello {
@Autowired
ConfigurableApplicationContext context;
@RequestMapping("/hello")
public String getHello(){
context.close();
return "ok~~";
}
}