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配置文件添加初始化器的接口与实现。

浙公网安备 33010602011771号