Spring Boot中的initializers的作用分析


在SpringApplication的實例屬性中有一個初始器的屬性:List<ApplicationContextInitializer<?>> initializers ,這些初始化器(initializers)是Spring Boot通過讀取每個jar包下的/META-INF/spring.factories文件中的配置獲取的。每一個initailizer都是一個實現了ApplicationContextInitializer接口的實例。ApplicationContextInitializer是Spring IOC容器中提供的一個接口:

package org.springframework.context;


public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {

    /**
     * Initialize the given application context.
     * @param applicationContext the application to configure
     */
    void initialize(C applicationContext);

}
ApplicationContextInitializer是一個回調接口,它會在ConfigurableApplicationContext的refresh()方法調用之前被調用,做一些容器的初始化工作。這一點我們也可以通過SpringApplication的實例run方法的實現代碼得到驗證,為了說明問題,再次貼一下這段代碼,注意下標紅的代碼和注釋就自然理解了。
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        FailureAnalyzers analyzers = null;
        configureHeadlessProperty();
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
            Banner printedBanner = printBanner(environment);
            context = createApplicationContext();
            analyzers = new FailureAnalyzers(context);
            prepareContext(context, environment, listeners, applicationArguments, printedBanner); // prepareContext方法中將會執行每個initializers的邏輯 refreshContext(context); // 執行bean的創建和實例化
            afterRefresh(context, applicationArguments);
            listeners.finished(context, null);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                        .logStarted(getApplicationLog(), stopWatch);
            }
            return context;
        }
        catch (Throwable ex) {
            handleRunFailure(context, listeners, analyzers, ex);
            throw new IllegalStateException(ex);
        }
    }

 



SpringBoot默認情況下提供了6個initializer,分別由2個jar提供:

 spring-boot-1.5.2.RELEASE.jar

  •   org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
  •   org.springframework.boot.context.ContextIdApplicationContextInitializer,
  •   org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
  •   org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer

  

   spring-boot-autoconfigure-1.5.2.RELEASE.jar

  •   org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,
  •   org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer

 

 Spring Boot對initializer的獲取過程如下:

initialize(Object[] sources)
  -->(Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class ))  //獲取initializer實例
      -->SpringFactoriesLoader.loadFactoryNames(type, classLoader))
      -->createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names)
        -->Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes)
        -->T instance = (T) BeanUtils.instantiateClass(constructor, args)
      -->AnnotationAwareOrderComparator.sort(instances)

       --> setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers)

   -->this.initializers = new ArrayList<ApplicationContextInitializer<?>>();

   -->this.initializers.addAll(initializers);    //存入List<ApplicationContextInitializer<?>> initializers

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM