IoC 之加载 BeanDefinition

IoC容器的使用过程

  • 获取资源
  • 获取BeanFactory
  • 根据新建的BeanFactory创建一个BeanDefinitionReader对象,该Reader对象为资源的解析器
  • 装载资源

装载过程

  • 2e6a48730e0fb17fb4cead5431550965807.jpg
  • BeanDefinitionReader 定义了统一的接口,然后AbstractBeanDefinitionReader提供了默认的实现
  • BeanDefinitionReader中加载资源的真正实现的代码是(以下代码基于XmlBeanDefinitionReader) :
    @Override
    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
       return loadBeanDefinitions(new EncodedResource(resource)); //转换成EncodedResource编码,保证内容读取的正确性
    }
    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 == null) {
          currentResources = new HashSet<>(4);
          this.resourcesCurrentlyBeingLoaded.set(currentResources);
       }
       //将当前的资源放入记录中,如果存在的话就抛出异常
       if (!currentResources.add(encodedResource)) {
          throw new BeanDefinitionStoreException(
                "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
       }
       try {
          InputStream inputStream = encodedResource.getResource().getInputStream();
          try {
             InputSource inputSource = new InputSource(inputStream);
             if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
             }
             //来了来了,核心逻辑,执行加载BeanDefinition
             return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
          }
          finally {
             inputStream.close();
          }
       }
       catch (IOException ex) {
          throw new BeanDefinitionStoreException(
                "IOException parsing XML document from " + encodedResource.getResource(), ex);
       }
       finally {
          currentResources.remove(encodedResource); //从缓存中 
          if (currentResources.isEmpty()) {
             this.resourcesCurrentlyBeingLoaded.remove();
          }
       }
    }
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
          throws BeanDefinitionStoreException {
    
       try {
          Document doc = doLoadDocument(inputSource, resource); //基于xml,获取Document实例
          int count = registerBeanDefinitions(doc, resource); //注册Bean信息
          if (logger.isDebugEnabled()) {
             logger.debug("Loaded " + count + " bean definitions from " + resource);
          }
          return count;
       }
       catch (BeanDefinitionStoreException ex) {
          throw ex;
       }
       catch (SAXParseException ex) {
          throw new XmlBeanDefinitionStoreException(resource.getDescription(),
                "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
       }
       catch (SAXException ex) {
          throw new XmlBeanDefinitionStoreException(resource.getDescription(),
                "XML document from " + resource + " is invalid", ex);
       }
       catch (ParserConfigurationException ex) {
          throw new BeanDefinitionStoreException(resource.getDescription(),
                "Parser configuration exception parsing XML from " + resource, ex);
       }
       catch (IOException ex) {
          throw new BeanDefinitionStoreException(resource.getDescription(),
                "IOException parsing XML document from " + resource, ex);
       }
       catch (Throwable ex) {
          throw new BeanDefinitionStoreException(resource.getDescription(),
                "Unexpected exception parsing XML document from " + resource, ex);
       }
    }
    //getValidationModeForResource(resource)  获取指定资源(XML)的验证方法
    //this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware())   获取Document实例
    
    protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
       return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
             getValidationModeForResource(resource), isNamespaceAware());
    }

本期遗留问题:

  • getValidationModeForResource(resource)
  • this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, getValidationModeForResource(resource), isNamespaceAware()) 获取Document实例
  • registerBeanDefinitions(doc, resource)

ps:本章为芋道源码学习笔记

转载于:https://my.oschina.net/u/4055223/blog/3098599

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值