spring源码解析beanFactory创建

前言

今天的主要内容是spring上下文刷新相关源码解析

正文

跟踪到这个类

org.springframework.web.context.ContextLoader#configureAndRefreshWebApplicationContext这行代码

//     上下文刷新
      wac.refresh();

找到org.springframework.context.ConfigurableApplicationContext#refresh这个接口的一个抽象实现org.springframework.context.support.AbstractApplicationContext#refresh

@Override
   public void refresh() throws BeansException, IllegalStateException {
//    门面模式,刷新和销毁上下文必须是同步的,这里加了一个锁
      synchronized (this.startupShutdownMonitor) {
         // Prepare this context for refreshing.准备这个上下文来刷新。
//       上下文刷新的前置工作
         prepareRefresh();

         // Tell the subclass to refresh the internal bean factory.初始化内部beanFactory TODO 天河
         ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

         // Prepare the bean factory for use in this context.
         prepareBeanFactory(beanFactory);

         try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
         }

         catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
               logger.warn("Exception encountered during context initialization - " +
                     "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
         }

         finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            resetCommonCaches();
         }
      }
   }

整体看下,这个方法采用了门面设计模式,代码看起来跟整洁,逻辑很清晰。

刷新和销毁上下文必须是同步的,这里加了一个锁

synchronized (this.startupShutdownMonitor) {

上下文刷新的前置工作

prepareRefresh();

跟踪到这个方法

org.springframework.context.support.AbstractApplicationContext#prepareRefresh spring上下文刷新之前的一些前置工作,主要是相关属性的解析

protected void prepareRefresh() {
      this.startupDate = System.currentTimeMillis();
      this.closed.set(false);
      this.active.set(true);

      if (logger.isInfoEnabled()) {
         logger.info("Refreshing " + this);
      }

      // Initialize any placeholder property sources in the context environment 解析占位符
      initPropertySources();

      // Validate that all properties marked as required are resolvable
      // see ConfigurablePropertyResolver#setRequiredProperties
//    验证Required的属性
      getEnvironment().validateRequiredProperties();

      // Allow for the collection of early ApplicationEvents,
      // to be published once the multicaster is available...
      this.earlyApplicationEvents = new LinkedHashSet<>();
   }

返回到这个方法org.springframework.context.support.AbstractApplicationContext#refresh

这一行代码

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

创建beanFactory。

org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory跟踪到这个方法

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//    刷新beanFactory
      refreshBeanFactory();
      ConfigurableListableBeanFactory beanFactory = getBeanFactory();
      if (logger.isDebugEnabled()) {
         logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
      }
      return beanFactory;
   }

刷新beanFactory

refreshBeanFactory();

跟踪到这个方法org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory 实现了上下文底层的beanFactory刷新,如果之前有beanFactory就关闭并再初始化一个beanFactory。

@Override
   protected final void refreshBeanFactory() throws BeansException {
//    如果存在beanFactory
      if (hasBeanFactory()) {
//       销毁bean
         destroyBeans();
         closeBeanFactory();
      }
      try {
         DefaultListableBeanFactory beanFactory = createBeanFactory();
         beanFactory.setSerializationId(getId());
         customizeBeanFactory(beanFactory);
         loadBeanDefinitions(beanFactory);
         synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
         }
      }
      catch (IOException ex) {
         throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
      }
   }

判断是否存在beanFactory

if (hasBeanFactory()) {
//       销毁bean
         destroyBeans();
         closeBeanFactory();
      }

跟踪到这个方法

org.springframework.context.support.AbstractApplicationContext#destroyBeans 销毁单例的bean

protected void destroyBeans() {
//    获取beanFactory,并销毁单例的bean TODO 销毁bean
      getBeanFactory().destroySingletons();
   }

找到这个方法

org.springframework.beans.factory.support.DefaultListableBeanFactory#destroySingletons

@Override
   public void destroySingletons() {
      super.destroySingletons();
//    清除记录的单例beanName的缓存
      this.manualSingletonNames.clear();
      clearByTypeCache();
   }

第一行代码调用了父类的这个方法

org.springframework.beans.factory.support.FactoryBeanRegistrySupport#destroySingletons

@Override
   public void destroySingletons() {
      super.destroySingletons();
//    清空beanFactory缓存
      this.factoryBeanObjectCache.clear();
   }

第一行代码又调用了父类的这个方法

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingletons

public void destroySingletons() {
      if (logger.isDebugEnabled()) {
         logger.debug("Destroying singletons in " + this);
      }
//    这里使用ConcurrentHashMap本地缓存单例的bean实例,访问次数比较多,提搞并发量
      synchronized (this.singletonObjects) {
         this.singletonsCurrentlyInDestruction = true;
      }

      String[] disposableBeanNames;
//    这里是用LinkedHashMap本地缓存销毁的bean实例
      synchronized (this.disposableBeans) {
         disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
      }
      for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
//       销毁单例的bean
         destroySingleton(disposableBeanNames[i]);
      }

      this.containedBeanMap.clear();
      this.dependentBeanMap.clear();
      this.dependenciesForBeanMap.clear();

//    同步清空缓存
      synchronized (this.singletonObjects) {
         this.singletonObjects.clear();
         this.singletonFactories.clear();
         this.earlySingletonObjects.clear();
         this.registeredSingletons.clear();
         this.singletonsCurrentlyInDestruction = false;
      }
   }

找到这行代码

destroySingleton(disposableBeanNames[i]);

进入到这个方法

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#destroySingleton

public void destroySingleton(String beanName) {
      // Remove a registered singleton of the given name, if any.删除单例的bean,从本地缓存中删除
      removeSingleton(beanName);

      // Destroy the corresponding DisposableBean instance.
      DisposableBean disposableBean;
      synchronized (this.disposableBeans) {
//       从本地缓存中删除
         disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
      }
//    bean销毁的逻辑
      destroyBean(beanName, disposableBean);
   }

最后

本次介绍到这里,以上内容仅供参考。下次bean销毁的源码解析。

扫码关注

进群讨论

快到碗里来

!

猜你喜欢

转载自my.oschina.net/u/3775437/blog/1810416