Spring框架学习[IoC容器载入Bean资源文件](四)

2014-11-24 03:05:57 · 作者: · 浏览: 7
nDefinitions(String location) throws BeanDefinitionStoreException {
  • return loadBeanDefinitions(location, null); }
  • public int loadBeanDefinitions(String location, Set actualResources) throws BeanDefinitionStoreException { //获取在IoC容器初始化过程中设置的资源加载器
  • ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) {
  • throw new BeanDefinitionStoreException( Cannot import bean definitions from location [ + location + ]: no ResourceLoader available);
  • } if (resourceLoader instanceof ResourcePatternResolver) {
  • try { //将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源
  • //加载多个指定位置的Bean定义资源文件 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
  • //委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能 int loadCount = loadBeanDefinitions(resources);
  • if (actualResources != null) { for (Resource resource : resources) {
  • actualResources.add(resource); }
  • } if (logger.isDebugEnabled()) {
  • logger.debug(Loaded + loadCount + bean definitions from location pattern [ + location + ]); }
  • return loadCount; }
  • catch (IOException ex) { throw new BeanDefinitionStoreException(
  • Could not resolve bean definition resource pattern [ + location + ], ex); }
  • } else {
  • //将指定位置的Bean定义资源文件解析为Spring IoC容器封装的资源 //加载单个指定位置的Bean定义资源文件
  • Resource resource = resourceLoader.getResource(location); //委派调用其子类XmlBeanDefinitionReader的方法,实现加载功能
  • int loadCount = loadBeanDefinitions(resource); if (actualResources != null) {
  • actualResources.add(resource); }
  • if (logger.isDebugEnabled()) { logger.debug(Loaded + loadCount + bean definitions from location [ + location + ]);
  • } return loadCount;
  • } }
  • //重载方法,调用loadBeanDefinitions(String); public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
  • Assert.notNull(locations, Location array must not be null); int counter = 0;
  • for (String location : locations) { counter += loadBeanDefinitions(location);
  • } return counter;
  • }

    loadBeanDefinitions(Resource...resources)方法和上面分析的3个方法类似,同样也是调用XmlBeanDefinitionReader的loadBeanDefinitions方法。

    从对AbstractBeanDefinitionReader的loadBeanDefinitions方法源码分析可以看出该方法做了以下两件事:

    首先,调用资源加载器的获取资源方法resourceLoader.getResource(location),获取到要加载的资源。

    其次,真正执行加载功能是其子类XmlBeanDefinitionReader的loadBeanDefinitions方法。

    7.资源加载器获取要读入的资源:

    XmlBeanDefinitionReader通过调用其父类DefaultResourceLoader的getResource方法获取要加载的资源,其源码如下:

    [java]
    1. //获取Resource的具体实现方法 public Resource getResource(String location) {
    2. Assert.notNull(location, Location must not be null); //这里除了带有classpath标识的Resource
    3. if (location.startsWith(CLASSPATH_URL_PREFIX)) { return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
    4. } else {
    5. try { //这里处理URL标识的Resource定位
    6. URL url = new URL(location); return new UrlResource(url);
    7. } catch (MalformedURLException ex) {
    8. //如果既不是classpath标识,又不是URL标识的Resource定位,则调用 //容器本身的getResourceByPath方法获取Resource
    9. return getResourceByPath(location); }
    10. } }

      FileSystemXmlApplicationContext容器提供了getResourceByPath方法的实现,就是为了处理既不是classpath标识,又不是URL标识的Resource定位这种情况。

      现在,Bean定义的Resource得到了,下面我们继续跟随程序执行方向,分析XmlBeanDefinitionReader的loadBeanDefinitions方法。

      8. XmlBeanDefinitionReader加载Bean定义资源:

      [java]
      1. //XmlBeanDefinitionReader加载资源的入口方法 public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
      2. //将读入的X