Spring源码解析<五> refresh() 阶段五

1,135 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情

            .....
            // 12. 完成容器的创建工作
            this.finishRefresh();
        } catch (BeansException var9) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }

            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            // 13. 清除缓存
            this.resetCommonCaches();
        }

    }
}

12. finishRefresh:完成容器的创建工作

protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning). 
   // 清除资源缓存(如扫描的ASM元数据)
   clearResourceCaches();

   // Initialize lifecycle processor for this context.
   //12.1 初始化生命周期处理器
   initLifecycleProcessor();

   // Propagate refresh to lifecycle processor first.
   //12.2 刷新生命周期处理器
   getLifecycleProcessor().onRefresh();

   // Publish the final event.
   12.3ContextRefreshedEvent:发布容器刷新完成的事件
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   //注册应用上下文到LiveBeansView
   LiveBeansView.registerApplicationContext(this);
}

12.1 初始化生命周期处理器

protected void initLifecycleProcessor() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   //先从Bean工厂获取lifecycleProcessor
   if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
      this.lifecycleProcessor =
            beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
      if (logger.isTraceEnabled()) {
         logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
      }
   }
   else {//如果Bean工厂中没有LifecycleProcesso就创建默认的DefaultLifecycleProcessor
      DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
      defaultProcessor.setBeanFactory(beanFactory);
      this.lifecycleProcessor = defaultProcessor;
      beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
               "[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
      }
   }
}

12.2 onRefresh():刷新生命周期处理器

这里会进入DefaultLifecycleProcessor中

public void onRefresh() {
   startBeans(true);
   //设置启动状态
   this.running = true;
}

从IOC容器中找出所有的 Lifecycle 类型的Bean,遍历回调 start 方法。

private void startBeans(boolean autoStartupOnly) {
   Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
   Map<Integer, LifecycleGroup> phases = new HashMap<>();
   lifecycleBeans.forEach((beanName, bean) -> {
      if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
         int phase = getPhase(bean);
         LifecycleGroup group = phases.get(phase);
         if (group == null) {
            group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
            phases.put(phase, group);
         }
         group.add(beanName, bean);
      }
   });
   if (!phases.isEmpty()) {
      List<Integer> keys = new ArrayList<>(phases.keySet());
      Collections.sort(keys);
      for (Integer key : keys) {
         phases.get(key).start();
      }
   }
}

实现了 Lifecycle 接口的Bean可以规范化它的生命周期,可以在IOC容器的启动、停止时,自动触发接口中定义的 start 方法和 stop 方法

12.3 ContextRefreshedEvent:发布容器刷新完成的事件

protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
   Assert.notNull(event, "Event must not be null");

   // Decorate event as an ApplicationEvent if necessary
   ApplicationEvent applicationEvent;
   //是否是容器事件
   if (event instanceof ApplicationEvent) {
      applicationEvent = (ApplicationEvent) event;
   }
   else {//如果不是进行包装
      applicationEvent = new PayloadApplicationEvent<>(this, event);
      if (eventType == null) {
         eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
      }
   }

   // Multicast right now if possible - or lazily once the multicaster is initialized
   if (this.earlyApplicationEvents != null) {
      this.earlyApplicationEvents.add(applicationEvent);
   }
   else {//通过广播器发布时间
      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
   }

   // Publish event via parent context as well...
   //如果有父类容器,父类容器也需要发布该事件
   if (this.parent != null) {
      if (this.parent instanceof AbstractApplicationContext) {
         ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
      }
      else {
         this.parent.publishEvent(event);
      }
   }
}

13. 清除缓存:resetCommonCaches

清除反射、注解、类型解析器、类加载器缓存

protected void resetCommonCaches() {
   ReflectionUtils.clearCache();
   AnnotationUtils.clearCache();
   ResolvableType.clearCache();
   CachedIntrospectionResults.clearClassLoader(getClassLoader());
}

总结

  1. 创建生命周期处理器LifecycleProcessor
  2. 实现Lifecycle接口的Bean在容器创建和关闭的时候会由LifecycleProcessor进行回调
  3. 发布容器刷新完成事件ContextRefreshedEvent