【Spring 源码解析】4、从AbstractApplicationContext.refresh()方法看BeanFactory创建过程


不管是ClassPathXmlApplicationContext还是AnnotationConfigApplicationContext,在构造方法中都会调用refreh()方法来刷新上下文,创建BeanFactory以及BeanDefinition。

AbstractApplicationContext中创建BeanFactory的方法,主要是在refresh()这个方法中:

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // 准备好刷新上下文(设置一些变量)
      prepareRefresh();
 
      /**
       * obtainFreshBeanFactory()方法中根据实现类的不同调用不同的refreshBeanFactory()方法
       * <-----  注解模式  ----->
       * 1. 如果是使用AnnotationConfigApplicationContext来初始化环境
       * 调用的是GenericApplicationContext#refreshBeanFactory()方法
       * {@link GenericApplicationContext#refreshBeanFactory()}
       * 在该方法中只是对beanFactory的一些变量进行设置
       * <----- XML配置模式  ----->
       *  2. 如果是使用ClassPathXmlApplicationContext来初始化环境
       * 调用的是{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
       * 由于还没有对beanFactory进行初始化,所以在该方法中,完成了对beanFactory的初始化操作
       * 并对设置的资源位置进行扫描, 解析
       * 注意:此方法是使用ClassPathXmlApplicationContext来初始化上下文是解析注册bean的重要入口   <-------------------重要
       */
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
      //对beanFactory进行属性设置
      prepareBeanFactory(beanFactory);
 
      try {
         //允许在子类中对bean工厂进行后处理。
         postProcessBeanFactory(beanFactory);
 
         /**
          * <-----  注解模式  ----->
          * 1. 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口) <--------------------重要
          * 在该方法中执行了
          *     {@link org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法
          *     对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作)          <--------------- 重要
          * 注意:
          *      1. 一般情况下, 此时beanFactory中只注册了这一个BeanFactoryPostProcessor类-->ConfigurationClassPostProcessor
          *     在{@link AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)}中注册的
          *     2. 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类, 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作
          *     然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息
          *
          * <----- XML配置模式  ----->
          * 2. 如果是使用ClassPathXmlApplicationContext来初始化环境
          *  默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器
          *  除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;
          *
          */
         invokeBeanFactoryPostProcessors(beanFactory);
 
         //注册拦截bean创建的bean后处理处理器。
         registerBeanPostProcessors(beanFactory);
 
         //为上下文初始化Message源,即不同的语言体,国际化处理
         initMessageSource();
 
         // 初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中
         initApplicationEventMulticaster();
 
         // 留给子类来初始化其他的Bean
         onRefresh();
 
         //在所有注册的bean中查找listener bean,注册到消息广播器中
         registerListeners();
 
         // 初始化剩下的单例(非延迟加载的,延迟加载的单例在第一次调用的时候初始化)
         finishBeanFactoryInitialization(beanFactory);
 
         //最后一步:完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
         finishRefresh();
      }
 
      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }
 
         // 销毁已创建的单例以避免资源悬空。
         destroyBeans();
 
         // Reset 'active' flag.
         cancelRefresh(ex);
 
         // Propagate exception to caller.
         throw ex;
      }
 
      finally {
         resetCommonCaches();
      }
   }
}

1. prepareRefresh()方法进行准备工作

protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    // Initialize any placeholder property sources in the context environment
    //空实现
    initPropertySources();
    // Validate that all properties marked as required are resolvable
    // see ConfigurablePropertyResolver#setRequiredProperties
    getEnvironment().validateRequiredProperties();
    // Allow for the collection of early ApplicationEvents,
    // to be published once the multicaster is available...
    this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}

属性校验AbstractEnvironment.validateRequiredProperties():

@Override
public void validateRequiredProperties() throws MissingRequiredPropertiesException {
    this.propertyResolver.validateRequiredProperties();
}

2. obtainFreshBeanFactory()方法获取BeanFactory

  • 如果是使用AnnotationConfigApplicationContext来初始化环境: 调用的是GenericApplicationContext#refreshBeanFactory()方法,在该方法中只是对beanFactory的一些变量进行设置;

  • 如果是使用ClassPathXmlApplicationContext来初始化环境: 调用的是AbstractRefreshableApplicationContext#refreshBeanFactory(), 由于还没有对beanFactory进行初始化, 所以在该方法中, 完成了对beanFactory的初始化操作, 并对设置的资源位置进行扫描, 解析。具体分析一下AbstractRefreshableApplicationContext#refreshBeanFactory():

@Override
protected final void refreshBeanFactory() throws BeansException {
    //如果已经存在,那么销毁之前的
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    //创建了一个DefaultListableBeanFactory对象
    DefaultListableBeanFactory beanFactory = createBeanFactory();
    beanFactory.setSerializationId(getId());
    customizeBeanFactory(beanFactory);
    loadBeanDefinitions(beanFactory);
    synchronized (this.beanFactoryMonitor) {
        this.beanFactory = beanFactory;
    }
}
2.1 实例化一个DefaultListableBeanFactory对象

调用createBeanFactory()方法:

protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}

BeanFactory接口接口实际上就是Bean容器,其继承体系:
beanfactory

2.2 BeanFactory定制

AbstractRefreshableApplicationContext.customizeBeanFactory方法用于给子类提供一个自由配置的机会,默认实现:

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    if (this.allowBeanDefinitionOverriding != null) {
        //默认false,不允许覆盖
        beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
    }
    if (this.allowCircularReferences != null) {
        //默认false,不允许循环引用
        beanFactory.setAllowCircularReferences(this.allowCircularReferences);
    }
}
2.3 Bean加载

Bean就是被Spring管理的对象,其实源码中并没有Bean这个东西,只有一个注解@Bean。但是有一个BeanDefinition来描述Bean。BeanDefinition就是Bean这个概念在Spring中的描述,有了BeanDefinition我们就可以创建Bean,BeanDefinition是Bean在spring中的定义形态。

BeanDefinition数据结构:
bd
AbstractXmlApplicationContext.loadBeanDefinitions,这个便是核心的bean加载过程了:

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    // Configure the bean definition reader with this context's
    // resource loading environment.
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    //默认空实现
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

XmlBeanDefinitionReader 就是负责从XML配置文件中解析BeanDefinition的。ResourceEntityResolver用于schema和dtd的解析。

(1)配置文件加载

而这个loadBeanDefinitions(beanDefinitionReader)方法内部,实际上就是调用了XmlBeanDefinitionReader的loadBeanDefinitions()方法:

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   Resource[] configResources = getConfigResources();
   if (configResources != null) {
       reader.loadBeanDefinitions(configResources);
   }
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
       reader.loadBeanDefinitions(configLocations);
   }
}

最终都会调用loadBeanDefinitions(EncodedResource encodedResource) 这个方法:

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
   // 注释 1.7 从资源文件中获取输入流
   InputStream inputStream = encodedResource.getResource().getInputStream();
   InputSource inputSource = new InputSource(inputStream);
   return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}

再执行doLoadBeanDefinitions()方法:

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
   try {
       Document doc = doLoadDocument(inputSource, resource);
       int count = registerBeanDefinitions(doc, resource);
       if (logger.isDebugEnabled()) {
           logger.debug("Loaded " + count + " bean definitions from " + resource);
       }
   return count;
    catch (Exception ex) {
       throw ex;
   }
}

其实重点是就是两行代码doLoadDocument()和registerBeanDefinitions()方法

  • doLoadDocument(inputSource, resource)是用来将xml文件解析成Document对象:
protected Document doLoadDocument(InputSource inputSource, Resource resource) {
   return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
       getValidationModeForResource(resource), isNamespaceAware());
}
(2) Bean解析注册

而registerBeanDefinitions(doc, resource)用来解析注册BeanDefinition的:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
   int countBefore = getRegistry().getBeanDefinitionCount();
   documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
   return getRegistry().getBeanDefinitionCount() - countBefore;
}
(2.1). 创建解析器

createBeanDefinitionDocumentReader():

protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
    return BeanDefinitionDocumentReader.class.cast
      //反射
      (BeanUtils.instantiateClass(this.documentReaderClass));
}

documentReaderClass默认是DefaultBeanDefinitionDocumentReader,这其实也是策略模式,通过setter方法可以更换其实现。

createReaderContext():

public XmlReaderContext createReaderContext(Resource resource) {
    return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
        this.sourceExtractor, this, getNamespaceHandlerResolver());
}

problemReporter是一个FailFastProblemReporter对象。
eventListener是EmptyReaderEventListener对象,此类里的方法都是空实现。
sourceExtractor是NullSourceExtractor对象,直接返回空,也是空实现。
getNamespaceHandlerResolver默认返回DefaultNamespaceHandlerResolver对象,用来获取xsd对应的处理器。
XmlReaderContext的作用感觉就是这一堆参数的容器,糅合到一起传给DocumentReader,并美其名为Context。可以看出,Spring中到处都是策略模式,大量操作被抽象成接口。

registerBeanDefinitions():

DefaultBeanDefinitionDocumentReader是BeanDefinitionDocumentReader的一个具体实现类,它的registerBeanDefinitions()方法实际调用的是doRegisterBeanDefinitions(doc.getDocumentElement())这个方法:

protected void doRegisterBeanDefinitions(Element root) {
   BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);
   //默认的命名空间即
   //http://www.springframework.org/schema/beans
   if (this.delegate.isDefaultNamespace(root)) {
       //检查profile属性
       String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
       if (StringUtils.hasText(profileSpec)) {
           //profile属性可以以,分割
           String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                   profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
           if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
               return;
           }
       }
   }
   preProcessXml(root);
   parseBeanDefinitions(root, this.delegate);
   postProcessXml(root);
   this.delegate = parent;
}

先调用createDelegate()方法创建一个BeanDefinitionParserDelegate对象,delegate的作用在于处理beans标签的嵌套。例如:

<?xml version="1.0" encoding="UTF-8"?>    
<beans>    
    <bean class="base.SimpleBean"></bean>
    <beans>
        <bean class="java.lang.Object"></bean>
    </beans>
</beans>

preProcessXml()方法是个空实现,供子类去覆盖,目的在于给子类一个把我们自定义的标签转为Spring标准标签的机会, 想的真周到。

(2.2). 命名空间解析

parseBeanDefinitions()是重点方法:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   if (delegate.isDefaultNamespace(root)) {
       NodeList nl = root.getChildNodes();
       for (int i = 0; i < nl.getLength(); i++) {
           Node node = nl.item(i);
           if (node instanceof Element) {
               Element ele = (Element) node;
               if (delegate.isDefaultNamespace(ele)) {
                   parseDefaultElement(ele, delegate);
               } else {
                   delegate.parseCustomElement(ele);
               }
           }
       }
   } else {
       delegate.parseCustomElement(root);
   }
}

对于非默认命名空间的元素交由delegate处理。如果是默认命名空间的元素值直接调用parseDefaultElement()方法解析。

默认命名空间解析

默认命名空间解析,即import, alias, bean, 以及嵌套的beans四种标签。parseDefaultElement():

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
   //"import"
   if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
       importBeanDefinitionResource(ele);
   }
   else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
       processAliasRegistration(ele);
   }
   else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
       processBeanDefinition(ele, delegate);
   }
   else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
       // recurse
       doRegisterBeanDefinitions(ele);
   }
}
  • importBeanDefinitionResource()解析import标签。
  • processAliasRegistration()解析alias标签。
  • doRegisterBeanDefinitions(ele);就是处理嵌套的beans标签,实际即使递归调用doRegisterBeanDefinitions()这个方法。
  • processBeanDefinition()解析bean标签,bean标签是Spring配置文件中最最常见的节点了。看一下processBeanDefinition(ele, delegate);这个方法是怎么处理bean标签的:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   if (bdHolder != null) {
       bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
       try {
           // Register the final decorated instance.
           BeanDefinitionReaderUtils.registerBeanDefinition
               (bdHolder, getReaderContext().getRegistry());
       }
       catch (BeanDefinitionStoreException ex) {
           getReaderContext().error("Failed to register bean definition with name '" +
                   bdHolder.getBeanName() + "'", ele, ex);
       }
       // Send registration event.
       getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
   }
}

首先就是通过delegate.delegate.parseBeanDefinitionElement(ele, bdHolder)获得一个BeanDefinitionHolder对象。然后调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());注册bdHolder。

前面说到非默认的标签会交给delegate.parseCustomElement(ele)方法处理,到这一步一看,默认的标签交给了delegate.parseBeanDefinitionElement(ele)方法处理。其实都是交给BeanDefinitionParserDelegate这个类来处理,只不过是不同的方法。直接看parseBeanDefinitionElement()方法:

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
   // 获取 ID 属性
   String id = ele.getAttribute(ID_ATTRIBUTE);
   // 获取 NAME 属性
   String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
   List<String> aliases = new ArrayList<>();
   if (StringUtils.hasLength(nameAttr)) {
       // 名称按照 , ; 进行分割
       String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
       aliases.addAll(Arrays.asList(nameArr));
   }
   String beanName = id;
   if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
       // 如果没有指定 id,将 name 的第一个值作为 id
       beanName = aliases.remove(0);
   }
   // 默认 null
   if (containingBean == null) {
       // 检查名字是否唯一,如果 id 重复了,将抛出错误
       // 内部 usedNames 是一个 HashSet,将会存储加载过的 name 和 aliases
       checkNameUniqueness(beanName, aliases, ele);
   }
   // 将公共属性放入 AbstractBeanDefinition,具体实现在子类 GenericBeanDefinition
   AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
   if (beanDefinition != null) {
       if (!StringUtils.hasText(beanName)) {
           if (containingBean != null) {
               // 如果 id 和 name 都是空,那个 spring 会给它生成一个默认的名称
               beanName = BeanDefinitionReaderUtils.generateBeanName(
                       beanDefinition, this.readerContext.getRegistry(), true);
           }
           else {
               beanName = this.readerContext.generateBeanName(beanDefinition);
               String beanClassName = beanDefinition.getBeanClassName();
               if (beanClassName != null &&
                       beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
                       !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                   aliases.add(beanClassName);
                   }
               }
           }
       }
       String[] aliasesArray = StringUtils.toStringArray(aliases);
       return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
   }
   return null;
}

该方法主要工作流程如下:

  • 提取元素中的 id, name 属性
  • 进一步解析其它所有属性并统一封装到 GenericBeanDefinition 类型的实例中
  • 检测到 bean 没有指定 beanName 使用默认规则生成 beanName
  • 再通过parseBeanDefinitionElement(ele, beanName, containingBean);方法解析其他属性,同时创建了一个GenericBeanDefinition对象。
  • 将获取到的信息封装到 BeanDefinitionHolder 的实例中

也就是在parseBeanDefinitionElement()这个方法里面获取了bean标签中的id和name以及其他属性,然后返回一个BeanDefinitionHolder对象

(2.3). 注册BeanDefinition

在DefaultBeanDefinitionDocumentReader的processBeanDefinition()方法中,拿到BeanDefinitionHolder对象对象之后,调用BeanDefinitionReaderUtils.registerBeanDefinition (bdHolder, getReaderContext().getRegistry())进行注册:

public static void registerBeanDefinition(
   BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
   // Register bean definition under primary name.
   String beanName = definitionHolder.getBeanName();
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
   // Register aliases for bean name, if any.
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
       for (String alias : aliases) {
           registry.registerAlias(beanName, alias);
       }
   }
}

registry其实就是DefaultListableBeanFactory对象,DefaultListableBeanFactory的registerBeanDefinition()方法其实主要就干了这么两件事:

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
   this.beanDefinitionMap.put(beanName, beanDefinition);
   this.beanDefinitionNames.add(beanName);
}

beanDefinitionMap其实就是BeanFactory中的一个ConcurrentHashMap:
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

beanDefinitionNames是BeanFactory中的一个List:
private volatile List beanDefinitionNames = new ArrayList<>(256);

然后registerAlias()方法的实现在其祖先类SimpleAliasRegistry,就是把beanName和alias键值对放在了一个ConcurrentHashMap里:
private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);

看一下BeanDefinition在BeanFactory中的有关数据结构如下图:

bd

到这里BeanDefinition也就解析生成并且注册到BeanFactory中了。

3. prepareBeanFactory(beanFactory)

准备类加载器的环境,对前面获取到的 beanFactory(ConfigurationListableBeanFactory) 进行“特征”相关的设置,包括:

(1)BeanExpressionResolver

这便是Spring3.0开始出现的Spel表达式的解释器。

beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
(2)PropertyEditorRegistrar

用于向Spring注册java.beans.PropertyEditor。在编写xml配置时,我们设置的值都是字符串形式,所以在使用时肯定需要转为我们需要的类型,PropertyEditor接口正是定义了这么个东西。

beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

(3)环境注入

在Spring中我们自己的bean可以通过实现EnvironmentAware等一系列Aware接口获取到Spring内部的一些对象。

// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
(4)依赖解析忽略

此部分设置哪些接口在进行依赖注入的时候应该被忽略:

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.ignoreDependencyInterface(ApplicationStartup.class);
(5)bean伪装

有些对象并不在BeanFactory中,但是我们依然想让它们可以被装配,这就需要伪装一下:

// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

伪装关系保存在一个Map<Class<?>, Object>里。

(6)LoadTimeWeaver

添加静态aop处理所需要的类:

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()));
}
(7)注册环境
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());
}

4. postProcessBeanFactory(beanFactory);

// Allows post-processing of the bean factory in context subclasses.

此方法允许子类在所有的bean尚未初始化之前注册BeanPostProcessor。空实现,留给子类实现, 允许在子类中对bean工厂进行后处理

5. invokeBeanFactoryPostProcessors(beanFactory);

// Invoke factory processors registered as beans in the context.

实例化并调用所有注册的 BeanFactoryPostProcessorBean,这些是后处理器,处理类型是 BeanFactory, Spring 容器允许在实例化 bean 前,读取 bean 信息和修改它的属性。
相当于在实例化前,给用户最后一次机会去修改 bean 信息。
还有一点,执行也可以有先后顺序,依据这些处理器是否实现 PriorityOrdered 、Order 接口,根据 order 值进行排序。

(1) 如果是使用AnnotationConfigApplicationContext来初始化环境(该方法是解析注册bean的重要入口)在该方法中执行了ConfigurationClassPostProcessor#processConfigBeanDefinitions} 方法对配置类进行解析(如果该注解bean是配置类则在这个方法里完成了包扫描操作)
(2) 如果是使用ClassPathXmlApplicationContext来初始化环境, 默认情况下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息, 并没有任何Spring内部所定义的BeanFactory后处理器; 除非用户自定义了BeanFactory后处理器, 需要对BeanFactory进行修改, 那么才会执行对应后处理器里面的方法;

注意: 注解模式下,此时BeanDefinitionMap中含有6个Spring内部处理器类(但是只有一个BeanFactoryPostProcessor类的实例–>ConfigurationClassPostProcessor), 其中通过ConfigurationClassPostProcessor类来解析配置类,完成包扫描,bean注册等操作; 然而, 在xml配置模式下, 此时BeanDefinitionMap只有自定义配置的BeanDefinition信息

6. registerBeanPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.

上面BeanFactoryPostProcessor是BeanFactory后置处理器,这里BeanPostProcessor是Bean后置处理器。此部分实质上是在BeanDefinitions中寻找BeanPostProcessor,之后调用BeanFactory.addBeanPostProcessor方法保存在一个List中,注意添加时仍然有优先级的概念,优先级高的在前面。

7. initMessageSource();

初始化此上下文的消息源,即不同的语言体,国际化处理。

8. initApplicationEventMulticaster();

//Initialize event multicaster for this context.

初始化应用消息广播,并放入"appliactionEventMulitcaster"bean中

9. onRefresh();

// Initialize other special beans in specific context subclasses.

模板方法,可被重写以添加特定于上下文的刷新工作。
在实例化单例之前调用特殊 bean 的初始化。
此实现为空,留给子类来初始化其他的Bean。

10. registerListeners();

// Check for listener beans and register them.

在所有注册的bean中查找listener bean,注册到消息广播器中

11. finishBeanFactoryInitialization(beanFactory);

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

完成 bean 容器的初始化,初始化剩下的非延迟加载的单例(延迟加载的单例在第一次需要调用的时候初始化)。

12.finishRefresh();

// Last step: publish corresponding event.

真真注册的最后一步,用来清除缓存,重置 Spring 核心中的公共内省缓存,因为我们可能再也不需要单例 bean 的元数据了。完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人


参考:


THE END.

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值