美文网首页
SpringBoot源码分析之系统初始化器

SpringBoot源码分析之系统初始化器

作者: handsomemao666 | 来源:发表于2020-08-23 16:30 被阅读0次

    SpringBoot系统初始化器作用

    • 上下文刷新即refresh方法前调用
    • 通常用在web环境中设置一些属性变量
    • 可以通过order接口进行排序

    1. 实现方式

    • 实现ApplicationContextInitializer类
    @Order(1)
    public class FirstInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            ConfigurableEnvironment environment = applicationContext.getEnvironment();
            environment.setRequiredProperties("mooc");
            Map<String, Object> map = new HashMap<>();
            map.put("key1", "value1");
            MapPropertySource mapPropertySource = new MapPropertySource("firstInitializer", map);
            environment.getPropertySources().addLast(mapPropertySource);
            System.out.println("run firstInitializer");
        }
    }
    
    • 在/resources/META-INF新建spring.factories配置文件
      key值为:org.springframework.context.ApplicationContextInitializer
      value值为具体的实现类:com.mooc.sb2.initializer.FirstInitializer
    org.springframework.context.ApplicationContextInitializer=com.mooc.sb2.initializer.FirstInitializer
    

    2. 源码分析

    注册系统初始化器
    在创建SpringApplication的时候,会注册系统初始化器

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
            this.resourceLoader = resourceLoader;
            Assert.notNull(primarySources, "PrimarySources must not be null");
            this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
            this.webApplicationType = WebApplicationType.deduceFromClasspath();
            //注册系统初始化器
            setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
            setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
            this.mainApplicationClass = deduceMainApplicationClass();
        }
    

    在注册系统初始化器时,通过SpringFactoriesLoader来加载配置在spring.factories配置文件中的系统初始化器。
    SpringFactoriesLoader是spring内部使用的通用工厂加载机器,从classpath下的多个jar包读取/resources/META-INF/spring.factories内容。文件内容必须是kv形式,key为全限定名,value为实现,多个实现用逗号进行分割。
    调用系统初始化器
    在refresh方法之前,prepareContext方法中会调用系统初始化器,源码如下:

    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
                SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
            context.setEnvironment(environment);
            postProcessApplicationContext(context);
            //调用系统初始化器
            applyInitializers(context);
            listeners.contextPrepared(context);
            if (this.logStartupInfo) {
                logStartupInfo(context.getParent() == null);
                logStartupProfileInfo(context);
            }
            // Add boot specific singleton beans
            ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
            beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
            if (printedBanner != null) {
                beanFactory.registerSingleton("springBootBanner", printedBanner);
            }
            if (beanFactory instanceof DefaultListableBeanFactory) {
                ((DefaultListableBeanFactory) beanFactory)
                        .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
            }
            // Load the sources
            Set<Object> sources = getAllSources();
            Assert.notEmpty(sources, "Sources must not be empty");
            load(context, sources.toArray(new Object[0]));
            listeners.contextLoaded(context);
        }
    

    相关文章

      网友评论

          本文标题:SpringBoot源码分析之系统初始化器

          本文链接:https://www.haomeiwen.com/subject/wkoijktx.html