• SpringBoot的重要类及接口


    ApplicationContextInitializer 

    首先看spring官网的介绍:

    翻译下来就是说:

    • 用于在spring容器刷新之前初始化Spring ConfigurableApplicationContext的回调接口。(就是在容器刷新之前调用该类的 initialize 方法。并将 ConfigurableApplicationContext 类的实例传递给该方法)
    • 通常用于需要对应用程序上下文进行编程初始化的web应用程序中。例如,根据上下文环境注册属性源或激活配置文件等。
    • 可排序的(实现Ordered接口,或者添加@Order注解)
    ApplicationContextInitializer三种实现方式

    首先新建一个类 MyApplicationContextInitializer并实现 ApplicationContextInitializer 接口。

    public class MyApplicationContextInitializer implements ApplicationContextInitializer {
       @Override
       public void initialize(ConfigurableApplicationContext applicationContext) {
           System.out.println("-----MyApplicationContextInitializer initialize-----");
       }
    }

    1、main函数中添加

    @SpringBootApplication
    public class MySpringBootApplication {
        public static void main(String[] args) {
            SpringApplication application = new SpringApplication(MySpringBootApplication.class);
            application.addInitializers(new MyApplicationContextInitializer());
            application.run(args);
        }
    }

    2、配置文件中配置

    context.initializer.classes=org.springframework.boot.demo.common.MyApplicationContextInitializer 

    3、SpringBoot的SPI扩展---META-INF/spring.factories中配置

    org.springframework.context.ApplicationContextInitializer=org.springframework.boot.demo.common.MyApplicationContextInitializer
    排序问题

    给 MyApplicationContextInitializer 加上Order注解:我们指定其拥有最高的排序级别。(值越小越早执行)

    @Order(Ordered.HIGHEST_PRECEDENCE)
    public class MyApplicationContextInitializer implements ApplicationContextInitializer{
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            System.out.println("-----MyApplicationContextInitializer initialize-----");
        }
    }

    除了使用Order注解,还可以采用实现Ordered接口的方式,排序验证结果都是一样的。

    通过源码分析ApplicationContextInitializer何时被调用
    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class[]{primarySource}, args);
    }
    
    public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }
    
    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();
    
        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            // 
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
    
            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }
    
        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

    在SpringBoot 2.3.6.RELEASE版本中,在this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);方法中调用。

    ApplicationRunner or CommandLineRunner

    应用服务启动时,加载一些数据和执行一些应用的初始化动作。如:删除临时文件,清除缓存信息,读取配置文件信息,数据库连接等。 

    SpringBoot提供了CommandLineRunner和ApplicationRunner接口。当接口有多个实现类时,提供了@order注解实现自定义执行顺序,也可以实现Ordered接口来自定义顺序。

    注意:数字越小,优先级越高,也就是@Order(1)注解的类会在@Order(2)注解的类之前执行。

    两者的区别在于:

    ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。想要更详细地获取命令行参数,那就使用ApplicationRunner接口。

    ApplicationRunner
    @Component
    @Order(value = 10)
    public class AgentApplicationRun2 implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments applicationArguments) throws Exception {
     
        }
    }
    CommandLineRunner
    @Component
    @Order(value = 11)
    public class AgentApplicationRun implements CommandLineRunner {
     
        @Override
        public void run(String... strings) throws Exception {
     
        }
    }

    接口不同于:

    ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。

  • 相关阅读:
    【视频+图文】带你快速掌握Java中含continue语句的双重for循环
    【小白视频学Java for循环】3分钟学会Java的for循环,让看懂for循环嵌套再不是难事
    【机器学习基础】交叉熵(cross entropy)损失函数是凸函数吗?
    【tf.keras】tensorflow datasets,tfds
    【python3基础】命令行参数及 argparse
    【机器学习实战】验证集效果比测试集好怎么办?
    [主动学习--查询策略] 01 Core-set
    Monte-Carlo Dropout,蒙特卡罗 dropout
    NumPy 会自动检测并利用 GPU 吗?
    Linux 和 Windows 查看 CUDA 和 cuDNN 版本
  • 原文地址:https://www.cnblogs.com/myitnews/p/14056294.html
Copyright © 2020-2023  润新知