SpringIOC容器初始化源码解析(4)—— 手撕Spring容器的刷新逻辑(较硬核)

本文阅读 15 分钟
首页 代码,Java 正文

refresh的源码如下:

@Override
public void refresh() throws BeansException, IllegalStateException { 
   // 给容器refresh加锁,避免容器处在refresh阶段时,容器进行了初始化或者销毁的操作
   synchronized (this.startupShutdownMonitor) { 
      // Prepare this context for refreshing.
      // 调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识,具体方法
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      // 告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从
      // 子类的refreshBeanFactory()方法启动,里面有抽象方法
      // 针对xml配置,最终创建内部容器,该容器负责 Bean的创建与管理,此步会进行BeanDefinition的注册
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 注册一些容器中需要的系统Bean.例如classloader,beanfactoryPostProcessor等
      prepareBeanFactory(beanFactory);

      try { 
         // Allows post-processing of the bean factory in context subclasses.
         // 为容器的某些子类指定特殊的BeanPost事件处理器,钩子方法
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         // 激活在容器中注册为bean的BeanFactoryPostProcessors
         // 方法扫描应用中所有BeanDefinition并注册到容器之中
         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();
      }
   }
}

在refresh方法里主要做的事情我以脑图的形式给出,各位读者可以从宏观上感受一下: img

直接在AbstractApplicationContext的refresh方法的第一行加上断点: img无论是注解还是xml的方式,都会执行这个refresh方法,用注解的程序作为入口进行调试。

调试程序源码

加锁是为了防止容器处在refresh阶段时,其他线程对容器进行了初始化或者销毁的操作。

先进入prepareRefresh方法里:

protected void prepareRefresh() { 
   // Switch to active.
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   // 设置容器状态为激活
   this.active.set(true);

   if (logger.isDebugEnabled()) { 
      if (logger.isTraceEnabled()) { 
         logger.trace("Refreshing " + this);
      }
      else { 
         logger.debug("Refreshing " + getDisplayName());
      }
   }

   // Initialize any placeholder property sources in the context environment.
   // 2.初始化Environment的 propertySources 属性
   // 样例<context:property-placeholder location="classpath*:/config/load.properties"/>
   initPropertySources();

   // Validate that all properties marked as required are resolvable:
   // see ConfigurablePropertyResolver#setRequiredProperties
   // 3.校验 Environment 的 requiredProperties 是否都存在
   // 请参考ConfigurablePropertyResolver#setRequiredProperties
   getEnvironment().validateRequiredProperties();

   // Store pre-refresh ApplicationListeners...
   if (this.earlyApplicationListeners == null) { 
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   }
   else { 
      // Reset local application listeners to pre-refresh state.
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }

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

  先记录时间用于日志记录,随后将容器的状态设为激活,然后根据配置的日至等级决定是否记录详细的日志。   然后初始化环境的propertySources属性(initPropertySources();),然后验证上一步之后还有没有一些必要的要设置上的属性没有加载进来(getEnvironment().validateRequiredProperties()),然后再看下是否有一些容器启动的时候加载进一些监听器,有的话则加载到earlyApplicationListeners这个监听者列表中,默认情况下为空,最后创建事件集合,因为仅有监听者是不够的。

  接下来就来到refresh方法的obtainFreshBeanFactory,对于xml方式来说,这一步特别重要,主要涉及到BeanDefinition的注册,但对于注解方式来说,该方法仅仅是调用了子类的refreshBeanFactory。

进入该方法:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { 
   refreshBeanFactory();
   return getBeanFactory();
}

refreshBeanFactory()是个抽象方法,等待子类来实现,可以step into进入到实际的方法里

@Override
protected final void refreshBeanFactory() throws IllegalStateException { 
   if (!this.refreshed.compareAndSet(false, true)) { 
      throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
   }
   this.beanFactory.setSerializationId(getId());
}

  对于注解来讲,它实际调用的是GenericApplicationContext的refreshBeanFactory方法,xml主要是生成DefaultListableBeanFactory的内部容器实例,然后将BeanDefinition实例给注册到内部容器实例中。

  针对于这里注解方式来讲,DefaultListableBeanFactory已经在注册类之前在调用容器的构造函数时就已经注册出来了,因此这里主要就是更新AnnotationConfigApplicationContecxt容器实例的刷新状态,把它内部的DefaultListableBeanFactory实例设置上序列化的id,就可以通过外部通过网络来逆序列化获得此处专属的DefaultListableBeanFactory实例

来到prepareBeanFactory(beanFactory)方法,此时已经获取到了DefaultListableBeanFactory的实例:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 
   // Tell the internal bean factory to use the context's class loader etc.
   // 给内置容器设置上外部容器的加载器
   beanFactory.setBeanClassLoader(getClassLoader());
   // 设置beanFactory的表达式语言处理器,Spring3开始增加了对语言表达式的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   // 为beanFactory增加一个默认的propertyEditor
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   // 添加该处理器的作用:当应用程序定义的Bean实现ApplicationContextAware接口时注入ApplicationContext
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   // 如果某个bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们
   // Spring 会通过其他方式来处理这些依赖。
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
   // 修正依赖,这里是注册一些自动装配的特殊规则,比如是BeanFactory class接口的实现类,则在运行时修指定为当前BeanFactory
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   // 注册早期后置处理器,用于检测内部bean作为应用程序监听器
   // ApplicationListenerDetector的作用就是判断某个Bean是否是ApplicationListener,
   // 如果是,加入到事件监听者队列。
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   // 如果找到一个LoadTimeWeaver,那么就准备将后置处理器“织入"bean工厂
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      // 为类型匹配设置临时类加载器
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
   // 注册默认environment环境bean
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { 
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { 
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { 
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}
  • 先给内置容器设置上外部容器的加载器,这样就可以让内部容器通过此类加载器去加载外部容器指定的资源了;
  • 第2步主要给内置容器设置上表达式语言处理器;
  • 之后就给内置容器加上一个默认的属性编辑器,用来编辑属性值的;
  • 之后会添加一个ApplicationContextAwareProcessor后置器,该后置器的作用是当应用程序定义的bean出现了ApplicationContextAware接口时,去给这些bean实例注入ApplicationContext对象;
  • 之后对于一些实现了特殊的接口的实现类,先忽略,随后通过其他方式再来处理;
  • 注册一些自动装配的规则,在运行时动态指定这些class对应的实现类;
  • 往容器里设置一个用来检查容器bean里是否有事件监听器的bean的beanPostProcessor;
  • 之后看看是否需要一个LTW织入器,在类加载的时候进行AOP的增强操作,如果有的话,就把该LWT级别的后置处理器添加到容器里;同时设置一个临时类加载器来负责加载并修改bean对应的行为;在AOP的时候会产生很多临时类,把他们放在临时类加载器里会更好;
  • 最后会设置一些默认环境的bean,承接一些默认的系统环境变量。

之后会来到postProcessBeanFactory(beanFactory),该方法允许子类去注册一些postProcessor,是一个钩子方法(子类可选择是否实现)

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { 
}

发现针对于本容器而言,是不需要注册子类的postProcessor的

接下来执行invokeBeanFactoryPostProcessors(beanFactory),进入到相应方法里 img

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { 

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   // 如果有BeanDefinitionRegistryPostProcessor的话优先执行
   Set<String> processedBeans = new HashSet<>();
   // 如果是BeanDefinitionRegistry类型的话
   if (beanFactory instanceof BeanDefinitionRegistry) { 
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      // 用于记录常规BeanFactoryPostProcessor
      List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
      // 用于记录BeanDefinitionRegistryPostProcessor
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
      // 遍历所有参数传递进来的 BeanFactoryPostProcessor(它们并没有作为bean注册在容器中)
      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { 
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { 
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else { 
            regularPostProcessors.add(postProcessor);
         }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) { 
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) { 
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { 
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      boolean reiterate = true;
      while (reiterate) { 
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) { 
            if (!processedBeans.contains(ppName)) { 
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      // 因为BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,所以这里
      // 也对所有 BeanDefinitionRegistryPostProcessor 调用其方法 postProcessBeanFactory()
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      // 对所有常规 BeanFactoryPostProcessor 调用其方法 postProcessBeanFactory()
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else { 
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) { 
      if (processedBeans.contains(ppName)) { 
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 
         orderedPostProcessorNames.add(ppName);
      }
      else { 
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
   for (String postProcessorName : orderedPostProcessorNames) { 
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
   for (String postProcessorName : nonOrderedPostProcessorNames) { 
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}

  将容器或者从参数传入进来的,包括实现了BeanDefinitionRegistryPostProcessor或BeanFactoryPostProcessor的容器级别的PostProcessor接口的类按照优先级来执行一遍;

  由于注解这一块先前obtainFreshBeanFactory方法执行的时候并没有把业务的BeanDefinition实例给定位、解析、注册到容器里,因此这里便调用实现了BeanDefinitionRegistryPostProcessor接口的ConfigurationClassPostProcessor这个后置处理器里面的postProcessBeanDefinitionRegistry方法,最终调用DefaultListableBeanFactory的方法来进行BeanDefinition实例的注册。

  完成了容器级别的后置处理器之后就是bean级别的后置处理器了registerBeanPostProcessors(beanFactory),将先前定义的bean级别的后置处理器给注册到容器里,方便之后在调用getBean方法去创建bean实例的时候,在特定的环节去触发这些后置处理器,执行一些特定的逻辑,如AOP织入。

注册完BeanPostProcessor后就到了下一步,initMessageSource()是进行一些国际化的配置,主要是针对不同的地区去展示不同的语言。

  接下来就是初始化事件发布器initApplicationEventMulticaster(),用于接受实现了ApplicationEventPublisher接口的类发送过来的不同的事件,并派发给不同的事件监听者来处理。

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() + "]");
      }
   }
}

  先判断容器有没有注册过自定义的事件发布器,有的话直接使用,否则就用默认的SimpleApplicationEventMulticaster作为事件发布器,进入到SimpleApplicationEventMulticaster

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { 
   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   Executor executor = getTaskExecutor();
   for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { 
      if (executor != null) { 
          // 异步发布事件
         executor.execute(() -> invokeListener(listener, event));
      }
      else { 
          // 同步发布事件
         invokeListener(listener, event);
      }
   }
}

该事件发布器既支持同步发布事件,又支持异步发布事件去给注册的监听器去做处理。

接下来执行onRefresh()方法

protected void onRefresh() throws BeansException { 
   // For subclasses: do nothing by default.
}

这是一个钩子方法,主要是预留给AbstractApplicationContext的子类用于初始化其他特殊的bean,该方法会发生在refresh的finishBeanFactoryInitialization(beanFactory);之前,也就是会发生在单例的bean的实例前去执行.

针对这个容器实例而言,并没有相关的onRefresh()方法的实现,onRefresh()方法主要是用在一些web容器上,比如AbstractRefreshableWebApplicationContext的onRefresh()方法:

@Override
protected void onRefresh() { 
   this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}

在这里会初始化一些和主题相关的bean

之后会执行registerListeners()方法,往先前已经注册出来的ApplicationEventMulticaster(事件发布器)中去注册相应的监听器,用来监听不同的事件,至此,事件、事件发布器、事件监听器就都有了。

接下来来到finishBeanFactoryInitialization(beanFactory)方法里,

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { 
   // Initialize conversion service for this context.
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { 
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no bean post-processor
   // (such as a PropertyPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   if (!beanFactory.hasEmbeddedValueResolver()) { 
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) { 
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   // 停止使用临时类加载器进行类型匹配
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   // 允许缓存所有bean定义元数据,不希望有进一步的更改
   beanFactory.freezeConfiguration();

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

  该方法首先看一下容器里有没有自动的类型转换器CONVERSION_SERVICE_BEAN_NAME,如果有则直接从容器里获取提供类型转换服务的bean实例。

  类型转换器就是在配置中给bean实例的属性赋值时需要将属性值转化成对应的类型,只有Spring容器本身不支持的一些类型转换需要这些转换器来处理。

  第12行往容器里注册默认的解析器,这个解析器能解析配置文件的值,并将他们注入到@value注解标记,或者xml里面的${}中间的变量里。

  再往后就是获取LoadTimeWeaverAware编织器的bean实例以便进行AOP的类加载操作,接下来就是停止使用临时类加载器进行类型匹配,因为在这个地方它已经完成了使命。

  beanFactory.freezeConfiguration()使得保存在内存里,先前刷新好的内容变得稳定可靠。

  beanFactory.preInstantiateSingletons()实例化所有剩余的(non-lazy-init非延时加载的)单例,高级容器的bean的默认scope就是singleton,非延迟加载。

进入到preInstantiateSingletons里:

public void preInstantiateSingletons() throws BeansException { 
   if (logger.isTraceEnabled()) { 
      logger.trace("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   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) { 
               final 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);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   for (String beanName : beanNames) { 
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) { 
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) { 
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else { 
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

  首先逐个遍历BeanDefinition的名字,然后根据名字去获取到相应的BeanDefinition实例,用RootBeanDefinition去承载合并在一起的BeanDefinition

RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

getMergedLocalBeanDefinition的主要作用就是兼容各种BeanDefinition,普通的bean在Spring加载bean定义的时候实例化出来的是GenericBeanDefinition,GenericBeanDefinition可直接转化成RootBeanDefinition,对于另外的具有继承关系的ChildBeanDefinition,它的parent会指定另外一个BeanDefinition,RootBeanDefinition 就会将ChildBeanDefinition和parent的属性给合并在一起。

  获取到了RootBeanDefinition之后先确保它不是抽象的、是单例的、是非延迟加载的,之后着手于实例化,实例化的时候先看一下是不是FactoryBean,是的话就加上&前缀去从容器里获取FactoryBean的实例,获取到了之后再看下FactoryBean里的bean是否是延迟加载的,如果不是延迟加载,并且相关的创建方法具有权限访问的话就将Factory中的bean实例通过getBean(beanName);创建出来。

if (isEagerInit) { 
    getBean(beanName);
}

  这里涉及到了SmartFactoryBean接口,该接口主要是留给框架内部服务来实现的,能够自动创建出所需要的的对象实例,同时还可以设定实例是延迟/非延迟加载的

default boolean isEagerInit() { 
   return false;
}

  在getBean(beanName)执行完之后,就会执行for循环,在循环里先调用getSingleton方法,主要是从容器的缓存里去获取bean的实例防止重复创建,获取到了之后会去看他有没有实现SmartInitializingSingleton接口,该接口作用是批量处理初始化好的Singleton实例。

  进入到afterSingletonsInstantiated方法中,是在EventListenerMethodProcessor类里

public void afterSingletonsInstantiated() { 
   ConfigurableListableBeanFactory beanFactory = this.beanFactory;
   Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set");
   String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
   for (String beanName : beanNames) { 
      if (!ScopedProxyUtils.isScopedTarget(beanName)) { 
         Class<?> type = null;
         try { 
            type = AutoProxyUtils.determineTargetClass(beanFactory, beanName);
         }
         catch (Throwable ex) { 
            // An unresolvable bean type, probably from a lazy bean - let's ignore it.
            if (logger.isDebugEnabled()) { 
               logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
            }
         }
         if (type != null) { 
            if (ScopedObject.class.isAssignableFrom(type)) { 
               try { 
                  Class<?> targetClass = AutoProxyUtils.determineTargetClass(
                        beanFactory, ScopedProxyUtils.getTargetBeanName(beanName));
                  if (targetClass != null) { 
                     type = targetClass;
                  }
               }
               catch (Throwable ex) { 
                  // An invalid scoped proxy arrangement - let's ignore it.
                  if (logger.isDebugEnabled()) { 
                     logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
                  }
               }
            }
            try { 
               processBean(beanName, type);
            }
            catch (Throwable ex) { 
               throw new BeanInitializationException("Failed to process @EventListener " +
                     "annotation on bean with name '" + beanName + "'", ex);
            }
         }
      }
   }
}

会去逐个遍历bean容器里的bean,如果bean不是Spring自带的bean(不是scopedTarget打头的),只要能够获取到它的type(类型),都会有机会执行processBean(beanName, type)

进入到processBean

private void processBean(final String beanName, final Class<?> targetType) { 
   if (!this.nonAnnotatedClasses.contains(targetType) &&
         AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
         !isSpringContainerClass(targetType)) { 

      Map<Method, EventListener> annotatedMethods = null;
      try { 
         annotatedMethods = MethodIntrospector.selectMethods(targetType,
               (MethodIntrospector.MetadataLookup<EventListener>) method ->
                     AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
      }
      catch (Throwable ex) { 
         // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
         if (logger.isDebugEnabled()) { 
            logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
         }
      }

      if (CollectionUtils.isEmpty(annotatedMethods)) { 
         this.nonAnnotatedClasses.add(targetType);
         if (logger.isTraceEnabled()) { 
            logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
         }
      }
      else { 
         // Non-empty set of methods
         ConfigurableApplicationContext context = this.applicationContext;
         Assert.state(context != null, "No ApplicationContext set");
         List<EventListenerFactory> factories = this.eventListenerFactories;
         Assert.state(factories != null, "EventListenerFactory List not initialized");
         for (Method method : annotatedMethods.keySet()) { 
            for (EventListenerFactory factory : factories) { 
               if (factory.supportsMethod(method)) { 
                  Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
                  ApplicationListener<?> applicationListener =
                        factory.createApplicationListener(beanName, targetType, methodToUse);
                  if (applicationListener instanceof ApplicationListenerMethodAdapter) { 
                     ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
                  }
                  context.addApplicationListener(applicationListener);
                  break;
               }
            }
         }
         if (logger.isDebugEnabled()) { 
            logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
                  beanName + "': " + annotatedMethods);
         }
      }
   }
}

如果不是Spring本身的class,并且类里有EventListener这个注解标签,这个注解标签是在方法上的 img 这些被标记了EventListener这个标签的bean实例的方法就会被当做事件监听器注册到容器里,去对其关注的事件进行一些处理,这就是注解方式的事件监听器的注册逻辑了。

之后来到finishRefresh方法里:

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

   // Initialize lifecycle processor for this context.
   // 为这个上下文初始化生命周期处理器
   initLifecycleProcessor();

   // Propagate refresh to lifecycle processor first.
   // 首先将刷新事件传播到生命周期处理器
   getLifecycleProcessor().onRefresh();

   // Publish the final event.
   // 发布最终事件
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   // 如果处于激活状态,将参与到 LiveBeansView MBean中
   LiveBeansView.registerApplicationContext(this);
}

该方法主要做一些收尾的工作。

最后会执行resetCommonCaches()方法,清空Spring内核中的一些通用缓存,了解即可。

本文为互联网自动采集或经作者授权后发布,本文观点不代表立场,若侵权下架请联系我们删帖处理!文章出自:https://wangjiawei.blog.csdn.net/article/details/121150664
-- 展开阅读全文 --
安全面试之XSS(跨站脚本攻击)
« 上一篇 07-24

发表评论

成为第一个评论的人

热门文章

标签TAG

最近回复