SpringBoot提供的扩展点

文章目录

  • ApplicationContextInitializer
  • SpringApplicationRunListener
  • ApplicationListener
  • ApplicationRunner
  • CommandLineRunner
  • ShutdownHook
  • 总结

ApplicationContextInitializer

  • 第一个就是ApplicationContextInitializer这个接口顾名思义就是在容器初始化时调用
  • 我们实现这个接口然后要在resources下创建一个META-INF/spring.factories的文件,然后将这个类写进去
  • 必须以这种方式,不然是没有效果的
  • 至于为什么这么做是有关于SpringBoot的加载方式,下一节会通过源码说明
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
	//参数是一个工厂类
	@Override
	public void initialize(ConfigurableApplicationContext applicationContext) {
		System.out.println("MyApplicationContextInitializer");
	}
}

SpringBoot提供的扩展点_第1张图片

  • 文件内容
org.springframework.context.ApplicationContextInitializer=
smoketest.tomcat.run.MyApplicationContextInitializer
  • 输出,在打印完Spring标识的时候就会调用这个方法
    SpringBoot提供的扩展点_第2张图片

SpringApplicationRunListener

  • 第二个是SpringApplicationRunListener接口,这个是一个监听器,这个接口封装了SpringBoot整个生命周期的方法
public interface SpringApplicationRunListener {
	//开始启动时调用
	default void starting() {
	}
	//准备环境时调用
	default void environmentPrepared(ConfigurableEnvironment environment) {
	}
	//准备容器时调用
	default void contextPrepared(ConfigurableApplicationContext context) {
	}
	//加载容器时调用
	default void contextLoaded(ConfigurableApplicationContext context) {
	}
	//启动完成时调用
	default void started(ConfigurableApplicationContext context) {
	}
	//启动完毕开始运行时调用
	default void running(ConfigurableApplicationContext context) {
	}
	//启动失败调用
	default void failed(ConfigurableApplicationContext context, Throwable exception) {
	}
  • 跟上边的接口一样,都是要实现以后然后写进到META-INF/spring.factories中
org.springframework.boot.SpringApplicationRunListener=
smoketest.tomcat.run.MySpringApplicationRunListener
public class MySpringApplicationRunListener implements SpringApplicationRunListener {

	private final SpringApplication application;

	private final String[] args;
	//必须定义这两个参数的构造方法
	public MySpringApplicationRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		System.out.println("MySpringApplicationRunListener");
	}

	@Override
	public void starting() {
		System.out.println("启动中");
	}

	@Override
	public void contextPrepared(ConfigurableApplicationContext context) {
		System.out.println("容器准备");
	}

	@Override
	public void environmentPrepared(ConfigurableEnvironment environment) {
		System.out.println("环境准备");
	}

	@Override
	public void contextLoaded(ConfigurableApplicationContext context) {
		System.out.println("容器加载");
	}

	@Override
	public void started(ConfigurableApplicationContext context) {
		System.out.println("启动完成");
	}

	@Override
	public void failed(ConfigurableApplicationContext context, Throwable exception) {
		System.out.println("启动失败");
	}

	@Override
	public void running(ConfigurableApplicationContext context) {
		System.out.println("运行中");
	}
}
  • 输出
    SpringBoot提供的扩展点_第3张图片
  • 这个接口中的大部分方法都是把工厂传给我们,所以我们拿到工厂以后可以很好的进行扩展

ApplicationListener

  • 第三个是ApplicationListener,实现这个接口只需要加上@Component注解就可以,然后配合ApplicationEvent使用
public class MyEvent extends ApplicationEvent {

	private int age;

	/**
	 * Create a new {@code ApplicationEvent}.
	 *
	 * @param source the object on which the event initially occurred or with
	 *               which the event is associated (never {@code null})
	 */
	public MyEvent(Object source, int age) {
		super(source);
		this.age = age;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}
//有事件则调用
@Component
public class MyApplicationListener implements ApplicationListener {
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		MyEvent myEvent = (MyEvent) event;
		System.out.println(myEvent.getAge());
	}
}
//在启动类代码后边传入这个对象
ConfigurableApplicationContext run =
 SpringApplication.run(SampleTomcatApplication.class, args);
		run.publishEvent(new MyEvent("aaa",12));
  • 输出这个age
    SpringBoot提供的扩展点_第4张图片

ApplicationRunner

  • 第四个是ApplicationRunner,实现这个接口也是只需要加@Component注解就可以
@Component
public class MyApplicationRunner implements ApplicationRunner {
	//拿到启动时传入的参数
	@Override
	public void run(ApplicationArguments args) throws Exception {
		System.out.println(Arrays.toString(args.getSourceArgs()));
	}
}
SpringApplication.run(SampleTomcatApplication.class, "123","456");
  • 输出
    在这里插入图片描述

CommandLineRunner

  • 第五个是CommandLineRunner,也是加上注解即可使用
@Component
public class MyCommandLineRunner implements CommandLineRunner {
	@Override
	public void run(String... args) throws Exception {
		System.out.println("MyCommandLineRunner");
	}
}
  • 输出
    在这里插入图片描述

ShutdownHook

  • 在SpringBoot中可以加上这么一个任务,来让SpringBoot结束时去执行这段任务,优雅停止
		Runtime.getRuntime().addShutdownHook(new Thread( () -> {
			System.out.println("springboot关闭");
		}));
  • 输出
    SpringBoot提供的扩展点_第5张图片

总结

  • 在SpringBoot中提供了很多扩展点,我也只是找到了其中这几个在源码中很明显的一些,可能还有一些是我没有发现的,如果还有的话可以私信告诉我。

  • 在这些扩展点中如果有多个的话可以再类上添加@Order注解或者实现Orderd接口来实现,数字越小越先执行,一般应该只能对一个接口的多个实现进行排序,这个暂时没有试过,不过ApplicationRunner和CommandLineRunner这两个接口是一起排序的。
    SpringBoot提供的扩展点_第6张图片

  • 我们可以通过这些扩展点来实现我们想要实现的功能。

你可能感兴趣的:(springboot,spring,java,spring,boot)