Spring扩展之一:ApplicationContextInitializer

1.介绍

用于Spring容器ConfigurableApplicationContext在刷新之前初始化Spring的回调接口。

通常在需要对应用程序上下文进行一些编程初始化的Web应用程序中使用。例如,注册属性源或针对上下文环境激活配置文件。

ApplicationContextInitializer鼓励处理器检测Spring的Ordered 接口是否已实现或@Order注释是否存在,并在调用之前对实例进行相应的排序。

public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {
    /**
     * 初始化给定的应用程序上下文.
     */
    void initialize(C applicationContext);
}

2.使用

//指定顺序,Order值越小优先级越高
@Order(100)
public class CustomApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        // 打印容器里面有多少个bean
        System.out.println("bean count=====" + applicationContext.getBeanDefinitionCount());
        // 打印所有 beanName
        System.out.println(applicationContext.getBeanDefinitionCount() + "个Bean的名字如下:");
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            System.out.println("--------"+beanName);
        }
    }
}

实现方式一: SPI扩展-配置文件中配置

在项目下的resources下新建META-INF文件夹,文件夹下新建spring.factories文件

org.springframework.context.ApplicationContextInitializer=com.yue.sso.CustomApplicationContextInitializer

 

实现方式二:main函数中添加

@SpringBootApplication
@ComponentScan(basePackages = "com.yue")
public class SsoApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(SsoApplication.class);
        application.addInitializers(new CustomApplicationContextInitializer());
        application.run(args);
    }
}

3.触发位置

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        configureIgnoreBeanInfo(environment);
        Banner printedBanner = printBanner(environment);
        context = createApplicationContext();
        exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
     // 准备容器:初始化在此完成
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        refreshContext(context);
        afterRefresh(context, applicationArguments);
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        listeners.started(context);
        callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, listeners);
        throw new IllegalStateException(ex);
    }
    try {
        listeners.running(context);
    }
    catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, null);
        throw new IllegalStateException(ex);
    }
    return context;
}
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
        SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    context.setEnvironment(environment);
    postProcessApplicationContext(context);
    // 执行所有ApplicationContextInitializer实现类初始化
    applyInitializers(context);
    listeners.contextPrepared(context);
    if (this.logStartupInfo) {
        logStartupInfo(context.getParent() == null);
        logStartupProfileInfo(context);
    }
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
    if (printedBanner != null) {
        beanFactory.registerSingleton("springBootBanner", printedBanner);
    }
    if (beanFactory instanceof DefaultListableBeanFactory) {
        ((DefaultListableBeanFactory) beanFactory)
                .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    if (this.lazyInitialization) {
        context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
    }
    Set<Object> sources = getAllSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    load(context, sources.toArray(new Object[0]));
    listeners.contextLoaded(context);
}

 

posted @ 2020-11-21 15:40  柒月丶  阅读(565)  评论(0)    收藏  举报