Spring系列二之springboot启动(下)

2024-08-06 15:37:34 浏览数 (2)

9 刷新IOC容器

此篇文章为springboot启动的下篇,紧接者上篇的刷新IOC容器

registerBeanPostProcessors(beanFactory),代码比较简单如下,把所有实现了BeanPostProcessor接口的Bean实例按照优先级添加到beanFactory的beanPostProcessors属性当中(beanPostProcessors是一个列表),在方法最后添加了一个ApplicationListenerDetector,在Bean初始化完成之后,如果是一个ApplicationListener实例,则将实例添加到上下文的Listeners属性当中

代码语言:javascript复制
public static void registerBeanPostProcessors(
       ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {


    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount()   1   postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
       if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
          BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
          priorityOrderedPostProcessors.add(pp);
          if (pp instanceof MergedBeanDefinitionPostProcessor) {
             internalPostProcessors.add(pp);
          }
       }
       else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
          orderedPostProcessorNames.add(ppName);
       }
       else {
          nonOrderedPostProcessorNames.add(ppName);
       }
    }

    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
       BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
       orderedPostProcessors.add(pp);
       if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
       }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
       BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
       nonOrderedPostProcessors.add(pp);
       if (pp instanceof MergedBeanDefinitionPostProcessor) {
          internalPostProcessors.add(pp);
       }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

initMessageSource(),初始换国际化的MessageSource,如果没有配置MessageSource,使用默认的DelegatingMessageSource

代码语言:javascript复制
protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
       this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
       // Make MessageSource aware of parent MessageSource.
       if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
          HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
          if (hms.getParentMessageSource() == null) {
             // Only set parent context as parent MessageSource if no parent MessageSource
             // registered already.
             hms.setParentMessageSource(getInternalParentMessageSource());
          }
       }
       if (logger.isTraceEnabled()) {
          logger.trace("Using MessageSource ["   this.messageSource   "]");
       }
    }
    else {
       // Use empty MessageSource to be able to accept getMessage calls.
       DelegatingMessageSource dms = new DelegatingMessageSource();
       dms.setParentMessageSource(getInternalParentMessageSource());
       this.messageSource = dms;
       beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
       if (logger.isTraceEnabled()) {
          logger.trace("No '"   MESSAGE_SOURCE_BEAN_NAME   "' bean, using ["   this.messageSource   "]");
       }
    }
}

initApplicationEventMulticaster(),比较简单,就是初始化了一个applicationEventMulticaster事件发布器

代码语言:javascript复制
protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
       this.applicationEventMulticaster =
             beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
       if (logger.isTraceEnabled()) {
          logger.trace("Using ApplicationEventMulticaster ["   this.applicationEventMulticaster   "]");
       }
    }
    else {
       this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
       beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
       if (logger.isTraceEnabled()) {
          logger.trace("No '"   APPLICATION_EVENT_MULTICASTER_BEAN_NAME   "' bean, using "  
                "["   this.applicationEventMulticaster.getClass().getSimpleName()   "]");
       }
    }
}

onRefresh(),如下,父类的onRefresh方法主要设置了应用的主题,和MessageSource的使用类似,可以设置ThemeSource,主要用于UI界面的主题切换功能,接着创建了一个WebServer,默认是tomcat

代码语言:javascript复制
protected void onRefresh() {
    super.onRefresh();
    try {
       createWebServer();
    }
    catch (Throwable ex) {
       throw new ApplicationContextException("Unable to start web server", ex);
    }
}

registerListeners(),如下,将context的ApplicationListeners注册到上文初始化的事件发布器ApplicationEventMulticaster当中

代码语言:javascript复制
protected void registerListeners() {
    // Register statically specified listeners first.
    for (ApplicationListener<?> listener : getApplicationListeners()) {
       getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
       getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // Publish early application events now that we finally have a multicaster...
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
       for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
          getApplicationEventMulticaster().multicastEvent(earlyEvent);
       }
    }
}

finishBeanFactoryInitialization(beanFactory),实例化所有非懒加载的Bean实例,最终是调用DefaultListable.preInstantiateSingletons()方法实例化,如下

代码语言:javascript复制
public void preInstantiateSingletons() throws BeansException {
    ......
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 加载所有非懒加载的Bean
    for (String beanName : beanNames) {
       RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
       if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
          if (isFactoryBean(beanName)) {
             Object bean = getBean(FACTORY_BEAN_PREFIX   beanName);
             if (bean instanceof FactoryBean) {
                FactoryBean<?> factory = (FactoryBean<?>) bean;
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                   isEagerInit = AccessController.doPrivileged(
                         (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                         getAccessControlContext());
                }
                else {
                   isEagerInit = (factory instanceof SmartFactoryBean &&
                         ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
                   getBean(beanName);
                }
             }
          }
          else {
             getBean(beanName);
          }
       }
    }

    // 所有非懒加载Bean实例加载完成之后,Bean如果实现了SmartInitializingSingleton,调用其回调方法
    // afterSingletonsInstantiated(),这个特性在xxl-job执行器的初始化中有使用过
    for (String beanName : beanNames) {
       Object singletonInstance = getSingleton(beanName);
       if (singletonInstance instanceof SmartInitializingSingleton) {
          StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
                .tag("beanName", beanName);
          SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
          if (System.getSecurityManager() != null) {
             AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                smartSingleton.afterSingletonsInstantiated();
                return null;
             }, getAccessControlContext());
          }
          else {
             smartSingleton.afterSingletonsInstantiated();
          }
          smartInitialize.end();
       }
    }
}

实例化的Bean的流程后续专门分析,这里先看个大概,实例化完成之后看看最后一步finishRefresh(),

代码语言:javascript复制
protected void finishRefresh() {
    // 清理一些资源的缓存
    clearResourceCaches();

    // 初始化LifecycleProcessor,从BeanFactory中获取LifecycleProcessor实例(没有就创建一个)
    // 用来处理所有实现了Lifecycle接口的实例(Lifecycle接口主要有start,stop,isRunning三个方法)
    initLifecycleProcessor();

    // onRefresh方法就是从BeanFactory中获取有实现了Lifecycle接口的实例,依次调用其start方法
    getLifecycleProcessor().onRefresh();

    // 发布一个ContextRefreshedEvent事件
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    if (!NativeDetector.inNativeImage()) {
       LiveBeansView.registerApplicationContext(this);
    }
}

至此刷新IOC容器就完成了

10 IOC容器刷新后处理

刷新后首先调用afterRefresh(context, applicationArguments)方法,默认是个空实现,然后调用了listeners.started(context, timeTakenToStartup)方法,关注第一行代码,通过上下文发布一个ApplicationStartedEvent事件

代码语言:javascript复制
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
    context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
    AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}

11 回调CommandRunner

最后获取容器中所有的实现了Runner接口的实例,回调其run方法,在elastic-job中定时的周期性任务就是通过此方式启动的

代码语言:javascript复制
private void callRunners(ApplicationContext context, ApplicationArguments args) {
    context.getBeanProvider(Runner.class).orderedStream().forEach((runner) -> {
       if (runner instanceof ApplicationRunner) {
          callRunner((ApplicationRunner) runner, args);
       }
       if (runner instanceof CommandLineRunner) {
          callRunner((CommandLineRunner) runner, args);
       }
    });
}

至此容器启动流程结束

0 人点赞