iteye_10284 2013-04-14 00:46
浏览 307
已采纳

在Sprng当中如何加载多个配置文件

第一种:

使用一个数组,将所有要加载的配置文件放入到数组当中

Java代码

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"a.xml","b.xml"});

第二种:

使用通配符,这种方法不知道对于不在同一个路径下的配置起不起作用,本人没试验过!

Java代码

ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/*.xml");

spring的源码是如何实现同时加载两个以上的配置文件的?

我的意思是源码在何处判断是否有两个路径,以及怎么去加载。

最好能贴上源代码。困惑了很久,请高手解决,不胜感激。

  • 写回答

1条回答 默认 最新

  • jinnianshilongnian 2013-04-14 08:24
    关注

    1、你疑惑的是classpath 加载方式
    2、那就分析ClassPathXmlApplicationContext
    */
    [url] public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
    throws BeansException {

        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }[/url]
    

    调用了setConfigLocations(configLocations);设置路径

    public void setConfigLocations(String[] locations) {
    if (locations != null) {
    Assert.noNullElements(locations, "Config locations must not be null");
    this.configLocations = new String[locations.length];
    for (int i = 0; i < locations.length; i++) {
    this.configLocations[i] = resolvePath(locations[i]).trim();
    }
    }
    else {
    this.configLocations = null;
    }
    }

    resolvePath用于替换${} 占位符

    这样就能解析出configLocations

    3、接下来加载bean
    [quote] 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);
    }
    }[/quote]

    [quote] 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;
    }
    [/quote]

    到了重点
    [quote]public int loadBeanDefinitions(String location, Set actualResources) throws BeanDefinitionStoreException {
    ResourceLoader resourceLoader = getResourceLoader();
    if (resourceLoader == null) {
    throw new BeanDefinitionStoreException(
    "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
    }

        if (resourceLoader instanceof ResourcePatternResolver) {
            // Resource pattern matching available.
            try {
                Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                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 {
            // Can only load single resources by absolute URL.
            Resource resource = resourceLoader.getResource(location);
            int loadCount = loadBeanDefinitions(resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
            }
            return loadCount;
        }
    }[/quote]
    

    3.1、重点
    3.1.1、getResourceLoader() --->
    在AbstractXmlApplicationContext(ClasspathXmlApplicationContext(继承它) beanDefinitionReader.setResourceLoader(this); 即ClasspathXmlApplicationContext本身 通过观察你会发现是DefaultResourceLoader

    它的解释:根据不同的前缀返回不同的Resource (到此其实就把你的疑问差不多解决了)

    • Will return a {@link UrlResource} if the location value is a URL,

      • and a {@link ClassPathResource} if it is a non-URL path or a
      • "classpath:" pseudo-URL.

    3.1.2、模式字符串的加载
    if (resourceLoader instanceof ResourcePatternResolver) {
    // Resource pattern matching available.
    try {
    Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);

    如果是模式 能找到多个--继续找下去 //classpath:aa*
    for (Resource resource : resources) {

    actualResources.add(resource);
    }

    其实你现在再去看下ClasspathResource就可以了

    具体使用可以参考
    [url]http://jinnianshilongnian.iteye.com/blog/1416322[/url]

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 聚类分析或者python进行数据分析
  • ¥15 如何用visual studio code实现html页面
  • ¥15 逻辑谓词和消解原理的运用
  • ¥15 三菱伺服电机按启动按钮有使能但不动作
  • ¥15 js,页面2返回页面1时定位进入的设备
  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?