Bean实例化之XML标签解析

        在Spring中,我们经常会通过以下几种方式来定义Bean:
        1. <bean/>
        2. @Bean
        3. @Component(@Service,@Controller)

        现在,我们使用第二种和第三种方式较多,要实例化某个类,直接加上@Component注解就可以了,但是在Spring早期的版本都是通过XML配置文件来定义Bean,这是我们的传统手艺,理解了配置文件的解析有助于后面Spring源码的学习。

        首先我们进入Spring容器初始化的核心方法——AbstractApplicationContext.refresh()方法中的 obtainFreshBeanFactory() 方法,负责把解析出来的XML标签封装成 BeanDefinition 对象:

/*
 * TODO
 *  1、创建BeanFactory对象
 *  2、xml解析
 *     传统标签解析:bean、import等
 *     自定义标签解析 如:<context:component-scan base-package="com.xiangxue.jack"/>
 *     自定义标签解析流程:
 *        a、根据当前解析标签的头信息找到对应的namespaceUri
 *        b、加载spring所有jar中的spring.handlers文件。并建立映射关系
 *        c、根据namespaceUri从映射关系中找到对应的实现了NamespaceHandler接口的类
 *        d、调用类的init方法,init方法是注册了各种自定义标签的解析类
 *        e、根据namespaceUri找到对应的解析类,然后调用paser方法完成标签解析
 *  3、把解析出来的xml标签封装成BeanDefinition对象
 */
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

进入AbstractRefreshableApplicationContext.refreshBeanFactory()方法:

@Override
protected final void refreshBeanFactory() throws BeansException {

   // TODO 如果BeanFactory不为空,则清除BeanFactory和里面的实例
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      // TODO 创建DefaultListableBeanFactory
      // BeanFactory 实例工厂
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());

      // TODO 设置是否可以循环依赖 allowCircularReferences
      // TODO 是否允许使用相同名称重新注册不同的bean实现.
      customizeBeanFactory(beanFactory);

      // TODO 解析XML,并把XML中的标签封装成BeanDefinition对象
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

进入AbstractXmlApplicationContext.loadBeanDefinitions(beanFactory)方法:

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
   // Create a new XmlBeanDefinitionReader for the given BeanFactory.
   // TODO 创建xml解析器,这里是委托模式
   XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

   // Configure the bean definition reader with this context's resource loading environment.
   beanDefinitionReader.setEnvironment(this.getEnvironment());

   //TODO 这里传一个this进去,因为ApplicationContext实现了ResourceLoader接口
   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);

   // TODO 主要看这个方法  重要程度 5
   loadBeanDefinitions(beanDefinitionReader);
}

        1. 创建xml解析器BeanDefinitionReader,这里运用了委托模式:XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        顺便多说两句,这些BeanDefinitionReader在我们日常工作中使用很少,但在Spring源码中用得多,相当于Spring源码的基础设施。还有一个AnnotatedBeanDefinitionReader,这个Reader可以直接把某个类转换为BeanDefinition,并解析该类上的注解,举例:

    @Test
    public void testXmlBeanDefinitionReader() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ScanBean.class);
        AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(applicationContext);
        // 将Teacher.class解析为BeanDefinition
        annotatedBeanDefinitionReader.register(Teacher.class);
        System.out.println(applicationContext.getBean("teacher"));
    }

        注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、
@Role、@Description

        进入AbstractXmlApplicationContext.loadBeanDefinitions(XmlBeanDefinitionReader reader)方法:

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
   Resource[] configResources = getConfigResources();
   if (configResources != null) {
    	reader.loadBeanDefinitions(configResources);
   }
   // TODO 获取需要加载的XML配置文件
   String[] configLocations = getConfigLocations();
   if (configLocations != null) {
    	// 委托给XmlBeanDefinitionReader来进行解析
    	reader.loadBeanDefinitions(configLocations);
   }
}

2. 通过 Reader 对象加载配置文件:reader.loadBeanDefinitions(configLocations);

进入AbstractBeanDefinitionReader.loadBeanDefinitions()方法:

@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
   Assert.notNull(locations, "Location array must not be null");
   int count = 0;
   // 配置文件有多个,加载多个配置文件
   for (String location : locations) {
   	// 调用父类loadBeanDefinitions方法
      count += loadBeanDefinitions(location);
   }
   return count;
}

进入 loadBeanDefinitions()的重载方法

所属类:org.springframework.context.support.AbstractBeanDefinitionReader

// TODO  字符串类型的XML文件路径,转换成Resource对象类型
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
   // 获取上下文对象
   ResourceLoader resourceLoader = getResourceLoader();
   if (resourceLoader == null) {
      throw new BeanDefinitionStoreException(
            "Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
   }

   if (resourceLoader instanceof ResourcePatternResolver) {
      // Resource pattern matching available.
      try {
         // 把字符串类型的XML文件路径,形如:classpath*:user/**/*-context.xml转换成Resource对象类型,
         // 其实就是用流的方式加载配置文件,然后封装成Resource对象,不重要,可以不看
         Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);

         // TODO 主要看这个方法 ** 重要程度 5
         int count = loadBeanDefinitions(resources);
         if (actualResources != null) {
            Collections.addAll(actualResources, resources);
         }
         if (logger.isTraceEnabled()) {
            logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
         }
         return count;
      }
      catch (IOException ex) {
         throw new BeanDefinitionStoreException(
               "Could not resolve bean definition resource pattern [" + location + "]", ex);
      }
   }
   else {
      // Can only load single resources by absolute URL.
      Resource resource = resourceLoader.getResource(location);
      int count = loadBeanDefinitions(resource);
      if (actualResources != null) {
         actualResources.add(resource);
      }
      if (logger.isTraceEnabled()) {
         logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
      }
      return count;
   }
}

进入 loadBeanDefinitions()的重载方法:

所属类:org.springframework.context.support.AbstractBeanDefinitionReader

@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
   Assert.notNull(resources, "Resource array must not be null");
   int count = 0;
   for (Resource resource : resources) {
      // 模板设计模式,调用到子类中的方法
      count += loadBeanDefinitions(resource);
   }
   return count;
}

进入XmlBeanDefinitionReader.loadBeanDefinitions()方法:

// 获取Resource对象中的xml文件流对象,转换成InputSource对象
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
   Assert.notNull(encodedResource, "EncodedResource must not be null");
   if (logger.isTraceEnabled()) {
      logger.trace("Loading XML bean definitions from " + encodedResource);
   }

   Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();

   if (!currentResources.add(encodedResource)) {
      throw new BeanDefinitionStoreException(
            "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
   }
   // 获取Resource对象中的XMl文件流对象
   try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
      // 把文件流对象包装成 InputSource
      // 注:InputSource是jdk包org.xml.sax中负责XML文档解析
      InputSource inputSource = new InputSource(inputStream);
      if (encodedResource.getEncoding() != null) {
         inputSource.setEncoding(encodedResource.getEncoding());
      }
      // TODO 主要看这个方法  重要程度 5
      return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
   }
   catch (IOException ex) {
      throw new BeanDefinitionStoreException(
            "IOException parsing XML document from " + encodedResource.getResource(), ex);
   }
   finally {
      currentResources.remove(encodedResource);
      if (currentResources.isEmpty()) {
         this.resourcesCurrentlyBeingLoaded.remove();
      }
   }

进入XmlBeanDefinitionReader.doLoadBeanDefinitions()方法:

3. 把配置文件封装成 Document 对象

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
      throws BeanDefinitionStoreException {

   try {
      // 把inputSource封装成Document文件对象,这是jdk的API
      Document doc = doLoadDocument(inputSource, resource);

      // 主要看这个方法,根据解析出来的document对象,拿到里面的标签元素并封装成BeanDefinition
      int count = registerBeanDefinitions(doc, resource);
      if (logger.isDebugEnabled()) {
         logger.debug("Loaded " + count + " bean definitions from " + resource);
      }
      return count;
   }

4. 创建 BeanDefinitionDocumentReader 对象,负责对 document 对象解析

// TODO 注册 BeanDefinition 对象
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
   // 又是一个委托模式,委托BeanDefinitionDocumentReader类进行document的解析
   BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
   int countBefore = getRegistry().getBeanDefinitionCount();
   // 主要看这个方法,createReaderContext(resource)是XmlReaderContext上下文,封装了XmlBeanDefinitionReader对象
   documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
   return getRegistry().getBeanDefinitionCount() - countBefore;
}

进入 registerBeanDefinitions()方法

所属类:org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
   this.readerContext = readerContext;
   // 主要看这个方法,把root节点传进去
   doRegisterBeanDefinitions(doc.getDocumentElement());
}
protected void doRegisterBeanDefinitions(Element root) {
    BeanDefinitionParserDelegate parent = this.delegate;
   this.delegate = createDelegate(getReaderContext(), root, parent);

   if (this.delegate.isDefaultNamespace(root)) {
      String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
      if (StringUtils.hasText(profileSpec)) {
         String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
               profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
         // We cannot use Profiles.of(...) since profile expressions are not supported
         // in XML config. See SPR-12458 for details.
         if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
            if (logger.isDebugEnabled()) {
               logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                     "] not matching: " + getReaderContext().getResource());
            }
            return;
         }
      }
   }
   // 冗余设计,模板方法
   preProcessXml(root);
   // TODO 主要看这个方法,标签具体解析过程
   parseBeanDefinitions(root, this.delegate);
   postProcessXml(root);

   this.delegate = parent;
}

进入DefaultBeanDefinitionDocumentReader.parseBeanDefinitions()方法:

5. 这是标签解析的地方,分为默认标签解析和自定义标签解析:

spring的默认标签只有4种:

  • <import/>

  • <alias/>

  • <bean/>

  • <beans/>

像<aop/><context/><mvc/>等都是自定义标签。

// TODO XML标签的具体解析过程
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
   // 获取根节点
   if (delegate.isDefaultNamespace(root)) {
      // 获取根节点里的所有子节点
      NodeList nl = root.getChildNodes();
      // 循环遍历所有子节点,对整个xml文件进行解析
      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 {
               // 自定义标签解析,通过委托类BeanDefinitionParserDelegate解析
               delegate.parseCustomElement(ele);
            }
         }
      }
   }
   else {
      delegate.parseCustomElement(root);
   }
}

5.1. 默认标签解析

5.1.1 delegate.parseDefaultElement()方法:

// TODO 默认标签的解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
   // import标签解析,可看可不看
   if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
      importBeanDefinitionResource(ele);
   }
   // alias标签解析 别名标签,可看可不看
   else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
      processAliasRegistration(ele);
   }
   // TODO bean标签,重要程度 5,必须看
   else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
      processBeanDefinition(ele, delegate);
   }
   else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
      // recurse
      doRegisterBeanDefinitions(ele);
   }
}

重点看bean标签解析:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   // 重点看这个方法,重要程度 5 ,解析document,封装成BeanDefinition
   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   if (bdHolder != null) {
      // 该方法功能不重要,设计模式重点看一下,装饰者设计模式,加上SPI设计思想
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
         // Register the final decorated instance.
         // 完成document到BeanDefinition对象转换后,对BeanDefinition对象进行缓存注册
         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));
   }
}

进入BeanDefinitionParserDelegate.parseBeanDefinitionElement()方法:

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
    ——省略不重要代码——
   // 检查beanName是否重复
   if (containingBean == null) {
      checkNameUniqueness(beanName, aliases, ele);
   }
   // 进入parseBeanDefinitionElement()方法->
   AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);

5.1.2  解析后封装成 BeanDefinitionHolder

进入parseBeanDefinitionElement()方法:

所属类:org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader

public AbstractBeanDefinition parseBeanDefinitionElement(
      Element ele, String beanName, @Nullable BeanDefinition containingBean) {
    ——省略不重要代码——

   try {
      // 创建GenericBeanDefinition对象
      AbstractBeanDefinition bd = createBeanDefinition(className, parent);

      // 解析bean标签的属性,并把解析出来的属性设置到BeanDefinition对象中
      parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
      bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

      // 解析bean中的meta标签
      parseMetaElements(ele, bd);

      // 解析bean中的lookup-method标签  重要程度:2,可看可不看
      parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

      // 解析bean中的replaced-method标签  重要程度:2,可看可不看
      parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

      // 解析bean中的constructor-arg标签  重要程度:2,可看可不看
      parseConstructorArgElements(ele, bd);

      // 解析bean中的property标签,通过BeanDefinition中的MutablePropertyValues,
      // 此类中用List<PropertyValue> propertyValueList集合来封装<property></property>对象
      parsePropertyElements(ele, bd);

      // 可以不看,用不到
      parseQualifierElements(ele, bd);

      bd.setResource(this.readerContext.getResource());
      bd.setSource(extractSource(ele));

      return bd;
   }
   ——省略不重要代码——

        进入 parseBeanDefinitionAttributes() 方法,最终的 BeanDefinition 属性在这里统一解析。BeanDefinitionParserDelegate 委托类包含了所有bean 标签元素的属性常量。

所属类:org.springframework.beans.factory.xml.BeanDefinitionParserDelegate

// 最终的BeanDefinition属性在这里统一解析
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
      @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {

   if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
      error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
   }
   else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
      bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
   }
   else if (containingBean != null) {
      // Take default from containing bean in case of an inner bean definition.
      bd.setScope(containingBean.getScope());
   }

   if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
      bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
   }

   String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
   if (isDefaultValue(lazyInit)) {
      lazyInit = this.defaults.getLazyInit();
   }
   bd.setLazyInit(TRUE_VALUE.equals(lazyInit));

   String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
   bd.setAutowireMode(getAutowireMode(autowire));

   if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
      String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
      bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
   }

   String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
   if (isDefaultValue(autowireCandidate)) {
      String candidatePattern = this.defaults.getAutowireCandidates();
      if (candidatePattern != null) {
         String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
         bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
      }
   }
   else {
      bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
   }

   if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
      bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
   }

   if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
      String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
      bd.setInitMethodName(initMethodName);
   }
   else if (this.defaults.getInitMethod() != null) {
      bd.setInitMethodName(this.defaults.getInitMethod());
      bd.setEnforceInitMethod(false);
   }

   if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
      String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
      bd.setDestroyMethodName(destroyMethodName);
   }
   else if (this.defaults.getDestroyMethod() != null) {
      bd.setDestroyMethodName(this.defaults.getDestroyMethod());
      bd.setEnforceDestroyMethod(false);
   }

   if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
      bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
   }
   if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
      bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
   }

   return bd;
}

进入BeanDefinitionParserDelegate.parsePropertyElement()解析property标签方法:

public void parsePropertyElement(Element ele, BeanDefinition bd) {
   String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
   if (!StringUtils.hasLength(propertyName)) {
      error("Tag 'property' must have a 'name' attribute", ele);
      return;
   }
   this.parseState.push(new PropertyEntry(propertyName));
   try {
      if (bd.getPropertyValues().contains(propertyName)) {
         error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
         return;
      }
      Object val = parsePropertyValue(ele, bd, propertyName);
      PropertyValue pv = new PropertyValue(propertyName, val);
      parseMetaElements(ele, pv);
      pv.setSource(extractSource(ele));
      bd.getPropertyValues().addPropertyValue(pv);
   }
   finally {
      this.parseState.pop();
   }
}

返回到 DefaultBeanDefinitionDocumentReader的 processBeanDefinition() 方法继续往下走,第一步已经完成 BeanDefinition 的属性解析,返回 BeanDefinitionHolder 对象,接下来要注册 

registerBeanDefinition。

5.1.3  注册 BeanDefinition 

进入 BeanDefinitionReaderUtils.registerBeanDefinition() 方法:

所属类:org.springframework.beans.factory.support.BeanDefinitionReaderUtils

public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {

   // Register bean definition under primary name.
   String beanName = definitionHolder.getBeanName();

   // 完成BeanDefinition的注册,重点看,重要程度 5
   registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

   // 建立别名和id的映射,这样就可以根据别名获取到id
   // Register aliases for bean name, if any.
   String[] aliases = definitionHolder.getAliases();
   if (aliases != null) {
      for (String alias : aliases) {
         registry.registerAlias(beanName, alias);
      }
   }
}

       进入DefaultListableBeanFactory.registerBeanDefinition()方法:

beanDefinitionNames是list,实例化的时候用;beanDefinitionMap用来放置 beanName 和 beanDefinition 对象。

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
    ——省略不重要代码——
   // 先判断BeanDefinition是否已经注册
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
 	——省略不重要代码——
      else {
         // 把beanDefinition缓存到map中
         this.beanDefinitionMap.put(beanName, beanDefinition);

         // 把beanName放到beanDefinitionNames list中,这个list着重记住,bean实例化的时候需要用到
         this.beanDefinitionNames.add(beanName);
         this.manualSingletonNames.remove(beanName);
      }
   }
}

        DefaultListableBeanFactory类的registerBeanDefinition() 方法,最终会把bean名称和beanDefinition放到 Map beanDefinitionMap = new ConcurrentHashMap<>(256)的 容器中,并且把bean名称放到List beanDefinitionNames = new ArrayList<>(256) 的 list容器中缓存起来。

5.2 自定义标签解析

5.2.1 获取自定义标签的 namespace 命令空间

        例如: http://www.springframework.org/schema/context

        String namespaceUri = getNamespaceURI(ele);

5.2.2 根据命令空间获取 NamespaceHandler 对象

        NamespaceUri 和 NamespaceHandler 之间会建立一个映射,Spring 会从所有的 jar 包中扫描 spring.handlers 文件,建立映射关系。

        NamespaceHandler handler =

this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);

        Map handlerMappings = getHandlerMappings();

        Object handlerOrClassName = handlerMappings.get(namespaceUri);

spring.handler 文件:

spring.handler中记录了namespaceUri和对应的解析类。

5.2.3 反射获取 NamespaceHandler 实例

        NamespaceHandler namespaceHandler =

(NamespaceHandler) BeanUtils.instantiateClass(handlerClass);

5.2.4 调用 init 方法:namespaceHandler.init();

5.2.5 调用 parse 方法

        handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

        回到DefaultBeanDefinitionDocumentReader.parseBeanDefinition()方法中的delegate.parseCustomElement()自定义标签解析:

// TODO 自定义标签交给BeanDefinitionParserDelegate 委托类来解析
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
   // 获取命名空间的URI
   String namespaceUri = getNamespaceURI(ele);
   if (namespaceUri == null) {
      return null;
   }
   // SPI设计,获取/META-INF/spring.handers中URI对应的Hander处理类
   NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
   if (handler == null) {
      error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
      return null;
   }
   // 执行 实现类NamespaceHandlerSupport 中的parse 方法
   return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
  •  a. 获取自定义标签的 namespace 命令空间,例如:http://www.springframework.org/schema/contex;
  • b. 根据命令空间获取 NamespaceHandler 对象通过 SPI 机制获取 spring 中所有 jar 包里面的 "META-INF/spring.handlers"文件,并且建立映射关系;
  • c. 反射获取 NamespaceHandler 实例;
  • d. 调用对应解析类 ContextNameHandler 的 init()方法。

DefaultNamespaceHandlerResolver.resolve()方法:

public NamespaceHandler resolve(String namespaceUri) {
   // 获取spring中所有jar包里面的 "META-INF/spring.handlers"文件,并且建立映射关系
   Map<String, Object> handlerMappings = getHandlerMappings();

   // 根据namespaceUri:http://www.springframework.org/schema/p,获取到命名空间NameHandler的处理类
   Object handlerOrClassName = handlerMappings.get(namespaceUri);

   else {
      String className = (String) handlerOrClassName;
         NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);

         // 调用handler处理类的init方法,在init方法中完成标签元素解析类的注册,即注册解析器
         namespaceHandler.init();
         handlerMappings.put(namespaceUri, namespaceHandler);
         return namespaceHandler;
      }
   }
}

 每个NameHander 的 init()方法注册不同标签对应不同的 parse 解析器:

public class ContextNamespaceHandler extends NamespaceHandlerSupport {

   @Override
   public void init() {
      registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
      registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
      registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
      registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
      registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
      registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
      registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
      registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
   }

}

注:每个 NameHander均继承于NamespaceHandlerSupport,如上面的ContextNamespaceHandler。

回到BeanDefinitionParserDelegate.parseCustomElement()自定义标签解析方法:

 

@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
   // 1.获取namespaceUri
   String namespaceUri = getNamespaceURI(ele);
   if (namespaceUri == null) {
      return null;
   }
   // 2.获取NamespaceHandler对象
   NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
   if (handler == null) {
      error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
      return null;
   }
   // 3.调用handler.parse()方法
   return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

进入parse()方法:

所属类:org.springframework.beans.factory.xml.NamespaceHandlerSupport

// TODO 委托BeanDefinitionParser类解析元素
public BeanDefinition parse(Element element, ParserContext parserContext) {
   // 获取自定义组件名对应的解析方法
   BeanDefinitionParser parser = findParserForElement(element, parserContext);
   // 调用ComponentScanBeanDefinitionParser实现类中的 parse 方法
   return (parser != null ? parser.parse(element, parserContext) : null);
}

进入findParserForElement()方法:

所属类:org.springframework.beans.factory.xml.NamespaceHandlerSupport

// TODO 从map中根据组件名称获取绑定的解析方法
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
   // 获取组件名称
   String localName = parserContext.getDelegate().getLocalName(element);
   // Map<String, BeanDefinitionParser> parsers = new HashMap<>()
   BeanDefinitionParser parser = this.parsers.get(localName);
   if (parser == null) {
      parserContext.getReaderContext().fatal(
            "Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
   }
   return parser;
}

        此处,this.parsers.get()之所以有值,是因为在/META-INF/spring.handers中URI对应的Hander处理类初始化的时候通过init()方法中执行registerBeanDefinitionParser(),来调用this.parsers.set('标签元素','解析类')设置的。

以 component-scan 标签解析为例,看解析原理:

进入ComponentScanBeanDefinitionParser.parse()方法:

a. 获取 base-package 属性

b. 创建注解扫描器 ClassPathBeanDefinitionScanner(扫描所有.class),ClassPathBeanDefinitionScanner继承于ClassPathScanningCandidateComponentProvider类 

/*
 * TODO 1、扫描路径.class后缀的文件
 *      2、要判断类上是否有注解
 *      3、GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
 *    	genericBeanDefinition.setBeanClass(BeanClass.class);
 *      4、完成beanDefinition注册
 */
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
   // 1.获取basePackage属性
   String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
   basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
   // 可以用逗号分开
   String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
         ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

   // 2.创建注解扫描器
   ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
   // 3.扫描并把扫描的类封装成beanDefinition对象,核心方法doScan(),重要程度 5
   Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
   // 4.完成组件注册,重要的后置处理类
   registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

   return null;
}

进入configureScanner()方法,看如何创建注解扫描器:

所属类:org.springframework.context.annotation.ComponentScanBeanDefinitionParser 

protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
   // 使用默认的过滤器
   boolean useDefaultFilters = true;
   // 使用默认filter @Component、@Service
   if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
      useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
   }

   // Delegate bean definition registration to scanner class.
   // 创建注解的扫描器,主要看这个方法
   ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
   scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
   scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());

   if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
      scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
   }

   try {
      // 解析子标签,不用看
      parseBeanNameGenerator(element, scanner);
   }
   catch (Exception ex) {
      parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
   }

   try {
      // 解析子标签,不用看
      parseScope(element, scanner);
   }
   catch (Exception ex) {
      parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
   }
   // 扫描含有"include-filter"和"exclude-filter"属性进行解析
   parseTypeFilters(element, scanner, parserContext);

   return scanner;
}

进入 createScanner()方法:

所属类:org.springframework.context.annotation.ComponentScanBeanDefinitionParser

// 创建扫描器
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
   return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
         readerContext.getEnvironment(), readerContext.getResourceLoader());
}

ClassPathBeanDefinitionScanner扫描器中默认扫描的注解类型为 Component.class,因此会扫描@Component 注解和@Service 注解,@Service注解继承自@Component 注解。

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
      Environment environment, @Nullable ResourceLoader resourceLoader) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
   this.registry = registry;

   // 使用默认的过滤器
   if (useDefaultFilters) {
      // @Service、@Component
      registerDefaultFilters();
   }
   setEnvironment(environment);
   setResourceLoader(resourceLoader);
}

进入registerDefaultFilters()方法,默认的扫描@Component 注解

所属类:org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider

protected void registerDefaultFilters() {
   // 过滤器中添加需要扫描的注解类型将注解添加到 AnnotationTypeFilter包装类
   this.includeFilters.add(new AnnotationTypeFilter(Component.class));
   // 确保类注解是 ClassPathScanningCandidateComponentProvider的类加载器
   ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
   try {
      this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
      logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
   }
   catch (ClassNotFoundException ex) {
      // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
   }
   try {
      this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
      logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
   }
   catch (ClassNotFoundException ex) {
      // JSR-330 API not available - simply skip.
   }
}

过滤器将会拦截 @Component 注解标注的类,包括被 @Component 标注的 @Service、@Repository、@Controller。

 将拦截到的注解添加到List includeFilters = new LinkedList<>() 容器中。

最后,根据匹配的 metadataReader 生成 ScannedGenericBeanDefinition。

a. 扫描过滤器中添加 include-filter 和 exclude-filter,ClassPathScanningCandidateComponentProvider类中有includeFilters和excludeFilters容器;

private final List<TypeFilter> includeFilters = new LinkedList<>();
private final List<TypeFilter> excludeFilters = new LinkedList<>();

b. 通过 scanner.doScan 方法,扫描封装进 beanDefiniton 对象:

先通过递归扫描 base-package 下的包,扫描出 classpath:/base-package 以.class 结尾的所有文件,然后再判断.class文件中是否有includeFilter中的注解@Component,根据过滤器扫描出具有@Service 和@Component 注解的类添加到对应的集合 Set,封装成BeanDefinition。

至此,注解扫描器创建过程完毕,注解类填充到List中。

接下来,返回 parse() 方法,进入ClassPathBeanDefinitionScanner.doScan() 方法:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
   Assert.notEmpty(basePackages, "At least one base package must be specified");
   Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
   for (String basePackage : basePackages) {
      // 扫描到有注解的类并封装成BeanDefinition对象
      Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
      // 循环扫描
      for (BeanDefinition candidate : candidates) {
         ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
         candidate.setScope(scopeMetadata.getScopeName());
         String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
         if (candidate instanceof AbstractBeanDefinition) {
            postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
         }
         if (candidate instanceof AnnotatedBeanDefinition) {
            // 支持了@Lazy @DependOn注解
            AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
         }
         if (checkCandidate(beanName, candidate)) {
            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
            //这里不看
            definitionHolder =
                  AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            beanDefinitions.add(definitionHolder);

            // BeanDefinition注册
            registerBeanDefinition(definitionHolder, this.registry);
         }
      }
   }
   return beanDefinitions;
}

进入ClassPathScanningCandidateComponentProvider.findCandidateComponents()方法,扫描候选的组件:

public Set<BeanDefinition> findCandidateComponents(String basePackage) {
   if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
      return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
   }
   else {
      // 扫描候选组件
      return scanCandidateComponents(basePackage);
   }
}

进入scanCandidateComponents(basePackage)方法:

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
   Set<BeanDefinition> candidates = new LinkedHashSet<>();
   try {
      String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
            resolveBasePackage(basePackage) + '/' + this.resourcePattern;

      // 这里递归寻找文件
      Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
      boolean traceEnabled = logger.isTraceEnabled();
      boolean debugEnabled = logger.isDebugEnabled();
      for (Resource resource : resources) {
         if (traceEnabled) {
            logger.trace("Scanning " + resource);
         }
         if (resource.isReadable()) {
            try {
               // 包装了类的基本信息的对象
               MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
               // 如果类上有includeFilter包含的注解,即满足条件的类
               if (isCandidateComponent(metadataReader)) {
                  ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                  sbd.setResource(resource);
                  sbd.setSource(resource);

回到 ClassPathBeanDefinitionScanner.doScan() 方法中的AnnotationConfigUtils.processCommonDefinitionAnnotations(candidate) 方法:

public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
   processCommonDefinitionAnnotations(abd, abd.getMetadata());
}

        进入AnnotationConfigUtils.processCommonDefinitionAnnotations()方法,AnnotatedTypeMetadata类中封装了收集到的所有注解,把有的注解添加到AnnotatedBeanDefinition(继承自GeniercBeanDefinition)。

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
   // 对@Lazy注解支持
   AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
   if (lazy != null) {
      abd.setLazyInit(lazy.getBoolean("value"));
   }
   else if (abd.getMetadata() != metadata) {
      lazy = attributesFor(abd.getMetadata(), Lazy.class);
      if (lazy != null) {
         abd.setLazyInit(lazy.getBoolean("value"));
      }
   }

   if (metadata.isAnnotated(Primary.class.getName())) {
      abd.setPrimary(true);
   }
   // 对@DependsOn注解支持
   AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
   if (dependsOn != null) {
      abd.setDependsOn(dependsOn.getStringArray("value"));
   }

   AnnotationAttributes role = attributesFor(metadata, Role.class);
   if (role != null) {
      abd.setRole(role.getNumber("value").intValue());
   }
   AnnotationAttributes description = attributesFor(metadata, Description.class);
   if (description != null) {
      abd.setDescription(description.getString("value"));
   }
}

        注册:回到ClassPathBeanDefinitionScanner.doScan()方法,进入 BeanDefinitionReaderUtils.registerBeanDefinition()方法:

        BeanDefinitionRegistry的类型是BeanFactory类型,因为BeanFactory实现了BeanDefinitionRegistry接口,BeanDefinitionRegistry接口有个方法registerBeanDefinition(String beanName, BeanDefiniton beanDefiniton),用来注册BeanDefinition,只有完成了注册,Spring容器才能拿到。

/**
* TODO : 向指定的bean工厂注册BeanDefinition
*/
public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();

		// 完成BeanDefinition的注册,重点看,重要程度 5
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// 建立别名和 id的映射,这样就可以根据别名获取到id
		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

注册的核心思想就是把BeanDefinition注册到DefaultListableBeanFactory中

进入registerBeanDefinition()方法,最终完成自定义标签的注册。

所属类:org.springframework.beans.factory.support.DefaultListableBeanFactory

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		// 先判断 BeanDefinition是否已经注册
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			// ...... 省略 ......
			else {
				// 把 beanDefinition 缓存到map中
				this.beanDefinitionMap.put(beanName, beanDefinition);
    
				//把 beanName 放到 beanDefinitionNames list中,bean实例化的时候需要用到
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}

回到 ComponentScanBeanDefinitionParser.parse()方法, 进入 registerComponents() 注册组件方法:

protected void registerComponents(
      XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
    ——省略不重要代码——
   if (annotationConfig) {

      // TODO 注册组件,这里注册了几个比较重要的BeanPostProcessor类
      // AutowiredAnnotationBeanPostProcessor,ConfigurationClassPostProcessor,CommonAnnotationBeanPostProcessor
      Set<BeanDefinitionHolder> processorDefinitions =
            AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
      for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
         compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
      }
   }

   readerContext.fireComponentRegistered(compositeDef);
}

进入AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source)方法,这里面注册了几个比较重要的类:

ConfigurationClassPostProcessor:扫描解析@Configuration、@Component、@Bean 注解的解析;

AutowiredAnnotationBeanPostProcessor:扫描解析@Value 和@Autowired 注解;

CommonAnnotationBeanPostProcessor:扫描解析@Resource 注解。

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
   if (beanFactory != null) {
      if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
         beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      }
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
         beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      }
   }

   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

   if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      //TODO 把ConfigurationClassPostProcessor风转成BeanDefinition,并
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
   if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
   }
     ——省略不重要代码——

       至此,自定义标签的解析过程全部完成。最终解析的标签封装成 BeanDefinition 并在Map容器缓存起来,把beanName放到了beanNames(一个list)。

       同时,核心方法refresh()中的 obtainFreshBeanFactory()方法也执行完成,解析出来的xml标签封装成BeanDefinition对象,然后通过getBeanFactory()方法返回 ConfigurableListableBeanFactory对象,至此创建填充BeanFactory的功能也全部完成。 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值