`
wsmajunfeng
  • 浏览: 497445 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring中使用classpath加载配置文件浅析

 
阅读更多

在应用 Spring 的工程中,使用 class path 的方式加载配置文件应该是最常用的做法,然而对大部分人来说,刚开始使用 Spring 时,几乎都碰到过加载配置文件失败的情况,除了配置上的错误外,很多时候是因为配置文件的路径和程序中指定的加载路径不一致,从而导致配置文件找不到,或是加载了错误地方的配置文件。本文将就 Spring 如何从 class path 中加载配置文件做一些简要的分析。

       

 

 

情形一:使用 classpath 加载且不含通配符

这是最简单的情形, Spring 默认会使用当前线程的 ClassLoader DE<getResource DE<DE<方法获取资源的 DE<DE<URL DE<DE<,如果无法获得当前线程的 DE<DE<ClassLoader DE<DE< DE<DE<Spring DE<DE<将使用加载类 DE<org.springframework.util.ClassUtils ClassLoader

    

 

1. 当工程目录结构如图所示 :

 

 
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
     

即配置文件放在 bin 目录中的 conf 文件夹里,这时使用

ApplicationContext context =

new ClassPathXmlApplicationContext("conf/application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 将加载 bin/conf 目录下的 application-context.xml 文件。 Spring 启动时的输出显示为:

Loading XML bean definitions from

class path resource [conf/application-context.xml]

    

 

2. 当工程目录结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
bin 目录下只有 .class 文件,没有配置文件,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context =

new ClassPathXmlApplicationContext("conf/application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 将加载 conf.jar 文件中 conf 目录下的 application-context.xml 文件。 Spring 启动时的输出显示为:

Loading XML bean definitions from

class path resource [conf/application-context.xml]

   

 

3. 当工程目录结构如图所示 :
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
即配置文件放在 bin 目录中的 conf 文件夹里,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context =

new ClassPathXmlApplicationContext("conf/application-context.xml"); 来创建 ApplicationContext 对象的话,由于没有使用 classpath* 前缀, Spring 只会加载一个 application-context.xml 文件。在 eclipse 中将会加载 bin/conf 目录下的 application-context.xml 文件,而 jar 包中的 conf/application-context.xml 并不会被加载, Spring 启动时的输出显示为:

Loading XML bean definitions from

class path resource [conf/application-context.xml]
    
    

情形二:使用 classpath 加载,包含通配符

碰到通配符的情况时, Spring 会通过使用路径中的非通配符部分先确定资源的大致位置,然后根据这个位置在确定具体的资源位置,结合下面给出的几种情况可以更好地理解 Spring 的这种工作方式

  

1. 当工程目录结构如图所示 :
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

即配置文件放在 bin 目录中的 conf 文件夹里,这时使用

ApplicationContext context = new

ClassPathXmlApplicationContext("conf/**/*application-context.xml");

来创建 ApplicationContext 对象的话, Spring 首先会通过路径中的非通配符部分即 conf ,先确定 conf 的路径,即 bin/conf 目录,然后从该目录下加载配置文件,由于使用了 /**/ 的方式,表明要加载 conf 目录下包括各级子目录中的所有配置文件,因此 bin/conf/application-context.xml 文件和

bin/conf/admin/admin-application-context.xml 都会被加载, Spring 启动时的输出显示为:

Loading XML bean definitions from file

[D:\myworkspace\spring-study\bin\conf\admin\admin-application-context.xml]

Loading XML bean definitions from file

[D:\myworkspace\spring-study\bin\conf\application-context.xml]

  

 

2 当工程目录结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
bin 目录下只有 .class 文件,没有配置文件,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context = new

ClassPathXmlApplicationContext("conf/**/*application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 首先会通过路径中的非通配符部分即 conf ,先确定 conf 的路径,即 conf.jar 中的 conf 目录,然后从该目录下加载配置文件,由于使用了 /**/ 的方式,表明要加载 conf 目录下包括各级子目录中的所有配置文件,因此 conf/application-context.xml 文件和

conf/admin/admin-application-context.xml 都会被加载, Spring 启动时的输出显示为:

Loading XML bean definitions from class path resource

[conf/admin/admin-application-context.xml]

Loading XML bean definitions from class path resource

[conf/application-context.xml]

  

 

3 当工程目录结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
即配置文件放在 bin 目录中的 conf 文件夹里,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context = new

ClassPathXmlApplicationContext("conf/**/*application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 首先会通过路径中的非通配符部分即 conf ,先确定 conf 的路径,在 eclipse 中是 bin/conf 目录,然后从该目录下加载配置文件,由于使用了 /**/ 的方式,表明要加载 conf 目录下包括各级子目录中的所有配置文件,因此 bin/conf/application-context.xml 文件和

bin/conf/admin/admin-application-context.xml 都会被加载,但 conf.jar 文件中的配置文件并不会被加载, Spring 启动时的输出显示为:

Loading XML bean definitions from file

[D:\myworkspace\spring-study\bin\conf\admin\admin-application-context.xml]

Loading XML bean definitions from file

[D:\myworkspace\spring-study\bin\conf\application-context.xml]
  
  

情形三:使用 classpath* 前缀且不包含通配符

使用 classpath* 前缀可以获取所有与给定路径匹配的 classpath 资源,从而避免出现两个不同位置有相同名字的文件, Spring 只加载其中一个的情况。

当工程目录结构如图所示 :
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
即配置文件放在 bin 目录中的 conf 文件夹里,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context = new

ClassPathXmlApplicationContext("classpath*:conf/application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 将会加载 bin 目录下的 application-context.xml 文件和 jar 包里的 application-context.xml 文件, Spring 启动时的输出显示为:

Loading XML bean definitions from URL

[file:/D:/myworkspace/spring-study/bin/conf/application-context.xml]

Loading XML bean definitions from URL

[jar:file:/D:/myworkspace/conf1.jar!/conf/application-context.xml]

  

情形四:使用 classpath* 前缀,包含通配符

当工程目录结构如图所示:

Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
即配置文件放在 bin 目录中的 conf 文件夹里,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context = new

ClassPathXmlApplicationContext("classpath*:conf/**/*application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 首先会通过路径中的非通配符部分即 conf ,先确定 conf 的路径,由于使用了 classpaht* 前缀,因此 bin 目录下的 conf jar 包里的 conf 都会被加载,同时由于使用了 /**/ 的方式,表明要加载 conf 目录下包括各级子目录中的所有配置文件,因此 bin/conf/application-context.xml

bin/conf/admin/admin-application-context.xml 以及 jar 包中的

conf/application-context.xml

conf/admin/admin-application-context.xml 都会被加载, Spring 启动时的输出显示为:

Loading XML bean definitions from file

[D:\myworkspace\spring-study\bin\conf\admin\admin-application-context.xml]

Loading XML bean definitions from file

[D:\myworkspace\spring-study\bin\conf\application-context.xml]

Loading XML bean definitions from URL

[jar:file:/D:/myworkspace/conf1.jar!/conf/admin/admin-application-context.xml]

Loading XML bean definitions from URL

[jar:file:/D:/myworkspace/conf1.jar!/conf/application-context.xml]

  

 

 

特别注意:

如果工程目录如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天
即配置文件直接放在 bin 目录中,同时在工程属性的 Java Build Path->Libraries 里导入 conf.jar 文件, jar 文件结构如图所示:
Spring中使用classpath加载配置文件浅析 - 大河之舟 - 龙绕青花,宏运中天

这时使用

ApplicationContext context = new

ClassPathXmlApplicationContext("classpath*:**/*application-context.xml"); 来创建 ApplicationContext 对象的话, Spring 只会加载

bin/application-context.xml bin/admin/admin-application-context.xml

jar 包中的配置文件并不会被加载。这是因为 Spring 使用 class path 加载配置文件时需要借助 JDK ClassLoader.getResources( String name) 方法,而该方法有一个局限:当传入的参数为空字符串时,即我们本意是想从根目录获取文件,这时 JDK 只会返回存在于文件系统中的资源,而在 jar 包中的资源并不会被返回。

    

 

我们在 eclipse 中写个简单的测试类就能很容易看到这点:

ClassLoader loader = Thread.currentThread ().getContextClassLoader();

Enumeration resources = loader.getResources( "" );

while (resources.hasMoreElements()) {

URL url = (URL)resources.nextElement();

        System. out .println(url);

}

运行测试类后,输出结果为:

file:/D:/myworkspace/spring-study/bin/

file:/D:/ProgramFiles/eclipse3.2/configuration/org.eclipse.osgi/bundles/47/1/.cp/

可以看到,获得的资源路径中并不包含 jar 包中的路径,因此 jar 包中的配置文件自然不能被 Spring 加载了。
   
  
  
     

参考资料:

Spring Framework 开发参考手册(中文翻译版)

http://www.redsaga.com/spring_ref/2.0/html/

 

java.lang.ClassLoader API 文档

http://java.sun.com/j2se/1.5.0/docs/api/

 

org.springframework.core.io.support. PathMatchingResourcePatternResolver API 文档

 
 
 
 
Spring可以通过指定classpath*:与classpath:前缀加路径的方式从classpath加载文件,如bean的定义文件.classpath*:的出现是为了从多个jar文件中加载相同的文件.classpath:只能加载找到的第一个文件.

比如 resource1.jar中的package 'com.test.rs' 有一个 'jarAppcontext.xml' 文件,内容如下:

<bean name="ProcessorImplA" class="com.test.spring.di.ProcessorImplA" />

resource2.jar中的package 'com.test.rs' 也有一个 'jarAppcontext.xml' 文件,内容如下:

<bean id="ProcessorImplB" class="com.test.spring.di.ProcessorImplB" />

通过使用下面的代码则可以将两个jar包中的文件都加载进来

ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath*:com/test/rs/jarAppcontext.xml");

而如果写成下面的代码,就只能找到其中的一个xml文件(顺序取决于jar包的加载顺序)

ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "classpath:com/test/rs/jarAppcontext.xml");

classpath*:的使用是为了多个component(最终发布成不同的jar包)并行开发,各自的bean定义文件按照一定的规则:package+filename,而使用这些component的调用者可以把这些文件都加载进来.

classpath*: 的加载使用了classloader的 getResources() 方法,如果是在不同的J2EE服务器上运行,由于应用服务器提供自己的classloader实现,它们在处理jar文件时的行为也许会有所不同。 要测试 classpath*: 是否有效,可以用classloader从classpath中的jar文件里加载文件来进行测试: getClass().getClassLoader().getResources("<someFileInsideTheJar>") 。(上面的例子是在sun的jre中运行的状态)


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kkdelta/archive/2010/04/20/5507799.aspx

 

 

分享到:
评论

相关推荐

    浅析Spring配置中的classpath:与classpath*:的区别

    Spring 配置中的classpath:与classpath*:的区别 Spring 配置中的classpath:与classpath*:的区别是 Spring 框架中一个常见的问题。本文主要介绍了这两种路径的区别、使用场景及注意事项,以帮助读者更好地理解和使用...

    Spring中如何加载多个配置文件.pdf

    ### Spring框架中加载多个配置文件的方法 在Spring框架中,加载多个配置文件是常见的需求之一。这不仅可以帮助我们更好地组织代码结构,还可以提高程序的可维护性和可扩展性。本文将详细介绍Spring框架中如何加载多...

    Spring动态加载配置文件

    在Spring框架中,动态加载配置文件是一项重要的功能,它允许我们在程序运行时改变或更新配置,而无需重启应用。这在开发和生产环境中都具有很高的实用价值,尤其是在配置需要频繁调整或者希望实现热更新的场景下。...

    如何加载jar包中的spring配置文件

    在Spring MVC项目中,加载jar包中的Spring配置文件是一个常见的需求,特别是在进行SSM(Spring、Spring MVC、MyBatis)整合时。SSM框架的整合通常涉及到多个配置文件的组织和管理,其中一部分配置可能会被打包到独立...

    Spring3.0 配置文件中加载Properties文件的小例子

    本篇将详细讲解如何在Spring 3.0的配置文件中加载Properties文件,以便在运行时动态获取和使用这些配置。 首先,我们需要一个Properties文件,例如`application.properties`,它通常放在项目的类路径根目录下。这个...

    spring读取jar中的配置文件

    在处理JAR内的配置文件时,通常会使用`@PropertySource`注解来指示Spring从特定资源加载属性。例如: ```java @Configuration @PropertySource("classpath:/config/application.properties") public class ...

    spring加载多个配置文件

    对于Java配置,Spring允许在配置类中使用`@ImportResource`注解来引入XML配置文件,或者直接通过`@Configuration`注解的类来引用其他配置类。例如: ```java @Configuration @ImportResource({"classpath:config1....

    Spring 加载多个配置文件

    除了直接通过 ApplicationContext 或者 ContextLoaderListener 加载配置文件,还可以在现有的 XML 配置文件中使用 `&lt;import&gt;` 标签导入其他的配置文件。这种方式允许开发者在主配置文件中引用其他辅助配置文件,...

    加载jar包中的spring配置文件

    2. **`classpath:`前缀**:当我们在Spring的配置中使用`classpath:`时,它表示资源位于类路径下的某个位置。例如,`classpath:spring-context.xml`意味着Spring会尝试在类路径下的`spring-context.xml`文件中加载...

    Spring通过在classpath自动扫描方式把组件纳入spring容器中管理

    在Spring框架中,自动扫描(Auto-Component Discovery)是一种便捷的方式,它允许开发者无需显式配置每个bean,就能将类路径下(classpath)的特定包及其子包中的组件(即带有特定注解的类)纳入Spring容器进行管理...

    Spring Boot多模块配置文件读取

    - 使用`spring.config.location`属性可以指定额外的配置文件位置,例如:`--spring.config.location=classpath:/module1.properties,classpath:/module2.properties`。 3. **命名规则与优先级** - Spring Boot...

    让spring加载自己的properties配置文件,在代码中获得配置信息

    本文将详细介绍如何让Spring自动加载自定义的`.properties`配置文件,并在代码中获取这些配置信息。 首先,我们需要创建一个`.properties`文件。这个文件通常命名为`application.properties`或根据项目需求自定义,...

    Spring中ApplicationContext加载机制

    Spring中ApplicationContext加载机制 ApplicationContext 是 Spring 框架中的核心组件之一,负责加载和管理应用程序中的 Bean 对象。在 Web 应用程序中,ApplicationContext 的加载机制是非常重要的, Spring 提供...

    Spring Boot加载配置文件的完整步骤

    Spring Boot支持placeholder的解析,可以在配置文件中使用${}符号来表示placeholder。这些placeholder会在加载配置文件时被解析成实际的值。例如,在application.properties文件中,可以使用${server.port}来表示...

    Java 加载配置文件的方式

    如果你的项目中使用了Spring框架,那么可以利用其强大的资源管理能力来加载配置文件。Spring支持.properties、.xml甚至.yaml或.yml格式的配置文件。例如,对于.properties文件: ```java @Configuration @...

    spring读取配置文件

    本篇文章将深入探讨如何在Spring中读取不同目录下的配置文件,以及使用`ClassPathXmlApplicationContext`和`FileSystemXmlApplicationContext`这两种不同的上下文环境来加载它们。 首先,让我们了解`...

    加载spring 文件,在web.xml中的配置

    当我们谈论“加载Spring文件,在web.xml中的配置”时,主要是指如何在Web应用启动时初始化Spring IoC(Inversion of Control,控制反转)容器并加载配置文件。 1. **使用ContextLoaderListener** `&lt;listener&gt;`标签...

    spring 启动时加载不同的文件

    ### Spring启动时根据配置文件加载不同文件的知识点详解 #### 一、背景介绍 在实际的应用开发中,根据运行环境的不同(例如开发环境、测试环境、生产环境等),应用程序往往需要连接不同的数据库或其他资源。为了...

    Springcloud Config支持本地配置文件的方法示例

    然而,在使用 Spring Cloud Config 时,开发者常常会遇到一个问题,即如何将本地配置文件加载到应用程序中。在这篇文章中,我们将详细介绍 Spring Cloud Config 支持本地配置文件的方法示例。 背景 在分布式系统中...

Global site tag (gtag.js) - Google Analytics