springboot源码学习笔记--系统初始化器

一,基本介绍:

       系统初始化器(ApplicationContextInitializer)是spring容器刷新之前执行的回调函数,可以向容器中注册一些系统属性,通过@order注解可以指定初始化器的执行顺序。springboot在启动的时候,首先会去构造SpringApplication对象,在构造器中通过setInitializers方法向环境中添加系统初始化器,利用springFactoriesLoader来加载META-INF目录下的spring.factories文件,将系统初始化器列表注册到springApplication对象之中。SpringApplication构造器源码如下:

 1     public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
 2         this.resourceLoader = resourceLoader;
 3         Assert.notNull(primarySources, "PrimarySources must not be null");
 4         this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
 5         this.webApplicationType = WebApplicationType.deduceFromClasspath();
 6         setInitializers((Collection) getSpringFactoriesInstances(
 7                 ApplicationContextInitializer.class));
 8         setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
 9         this.mainApplicationClass = deduceMainApplicationClass();
10     }

其中setInitializers方法就是去设置系统初始化器列表,getSpringFactoriesInstances方法会加载,初始化并排序定义的系统初始化器,其源码如下:

 1     private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
 2             Class<?>[] parameterTypes, Object... args) {
 3         ClassLoader classLoader = getClassLoader();
 4         // Use names and ensure unique to protect against duplicates
 5         Set<String> names = new LinkedHashSet<>(
 6                 SpringFactoriesLoader.loadFactoryNames(type, classLoader));
 7         List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
 8                 classLoader, args, names);
 9         AnnotationAwareOrderComparator.sort(instances);
10         return instances;
11     }

第一步:调用loadFactoryNames方法,,加载META-INF目录下spring.factories文件中定义的系统初始化器,以键值对的形式存储起来,spring.factories定义初始化器形式如下:

1 # 接口名->接口实现的类名
2 org.springframework.context.ApplicationContextInitializer=

第二步:调用createSpringFactoriesInstances方法对系统初始化器进行实例化。

第三步:调用AnnotationAwareOrderComparator的sort方法,根据添加的@order注解进行排序,值越小优先级越高,越先被执行;如果自定义实现初始化器时,在application.properties配置文件中,通过属性context.initializer.classes进行注册时,会被DelegatingApplicationContextInitializer初始化器发现,最先被执行,因为其内部定义的order属性值被定义为0,其优先级最高。

二,自定义实现系统初始化器

       自定义系统初始化一般都会去实现ApplicationContextInitializer接口,在initialize方法中向环境中添加系统属性。

@Order(1)
public class FirstInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        Map<String, Object> map = new HashMap<>();
        map.put("key1", "value1");
        MapPropertySource mapPropertySource = new MapPropertySource("fistInitializer", map);
        environment.getPropertySources().addLast(mapPropertySource);
        System.out.println("run fistInitializer");
    }
}

   注册自定义实现的系统初始化器有三种方式:

(1)通过在resources/META-INF目录下创建spring.factories文件,在其中定义系统初始化器的键值对。

org.springframework.context.ApplicationContextInitializer=com.wrq.quickstart.initializer.FirstInitializer

(2)手动创建SpringApplication对象,调用addInitializers方法,向springboot环境中注册系统初始化器。

(3)在application.properties配置文件添加初始化器的接口与实现。

posted @ 2021-05-24 23:11  Way_Run  阅读(116)  评论(0)    收藏  举报