2018-06-10 spring源码学习

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationConfig.xml"));

MyBean myBean = (MyBean) beanFactory.getBean("myBean")

上面是一个最基础的spring的使用方式,简单的两行代码包含的逻辑是确是值得深究的.

首先通过传入一个classPathResource的对象.将这个对象传入beanFactory的构造器其中.我们跟如XMLBeanFactory代码中可以看到如下代码:

public XmlBeanFactory(Resource resource)throws BeansException {

this(resource, null);

}

public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory)throws BeansException {

super(parentBeanFactory);

  this.reader.loadBeanDefinitions(resource);

}

可以看到,在XMLbeanFactory对象中使用了XMLBeanDefinitionReader,来进行解析XML文件,

我们可以看到调用了this.reader.loadBeanDefinitions(resource)来解析.

继续跟如这个方法之后可以看到更为复杂的逻辑:

public int loadBeanDefinitions(Resource resource)throws BeanDefinitionStoreException {

// new EncodeResource 将resource对象包装EncodeResource, 主要用来设置编码属性

  return loadBeanDefinitions(new EncodedResource(resource));

}

这方法首先将传入的resource对象进行了封装,进行编码的设置,以后后续会使用编码.继续跟进代码看到如下

public int loadBeanDefinitions(EncodedResource encodedResource)throws BeanDefinitionStoreException {

Assert.notNull(encodedResource, "EncodedResource must not be null");

  if (logger.isInfoEnabled()) {

logger.info("Loading XML bean definitions from " + encodedResource.getResource());

  }

// 通过属性来记录已经加载过的资源, 取到的是已经加载过的资源列表

  Set 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 {

// 从原始的resource对象中取到inputStream

      InputStream inputStream = encodedResource.getResource().getInputStream();

      try {

// 构造InputSource对象

        InputSource inputSource =new InputSource(inputStream);

        if (encodedResource.getEncoding() !=null) {

// 为inputResource设置编码

            inputSource.setEncoding(encodedResource.getEncoding());

        }

// 进入加载beanDefinitions方法,传入的资源是inputSource 和原本的Resource对象

        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();

      }

}

}

首先会在xmlBeandefinitionReader的属性中记录下已经加载的资源文件

然后从原始的resource对象中取到inputStream, inputStream有封装称了inputSource,这个对象是为了读取XML文件准备的,最后进入真正的逻辑核心部分

doLoadBeanDefition(inputResource, encodeResource.getResource());

明天继续!!!

你可能感兴趣的:(2018-06-10 spring源码学习)