MessageSource和PropertyPlaceholderConfigurer无法加载消息,但使用类路径*

时间:2011-09-27 19:34:49

标签: spring java-ee classpath

我的applicationContext.xml位于路径:

src/main/resources/META-INF/spring

和属性文件位于路径中:

src/main/resources/messages

我在web.xml中加载spring上下文,如下所示:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:META-INF/spring/applicationContext.xml</param-value>
</context-param>

当我按如下方式配置MessageSource和PropertyPlaceholderConfigurer时:

<bean id="propertyPlaceholderConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:messages/apps.properties</value>        
        </list>
    </property>
</bean>

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>classpath:messages/ValidationMessages</value>
            <value>classpath:messages/app</value>
        </list>
    </property>
    <property name="defaultEncoding" value="UTF-8"/>
</bean>

它们都不起作用,只有在我将classpath更改为classpath*时才有效 有什么想法吗?

2 个答案:

答案 0 :(得分:3)

来自Spring documentation

  

4.7.2.2 classpath *:前缀

     

[...]位置字符串可以使用特殊的classpath*:前缀:[...]

     

此特殊前缀指定必须获取与给定名称匹配的所有类路径资源[...],然后合并以形成最终的应用程序上下文定义。

您确定CLASSPATH上没有其他messages/apps.properties文件巧合优先并覆盖您的文件吗?此描述表明,在使用*时,您可能会有几个相同的命名文件合并。

您可以通过致电:

来查看
SomeClass.class.getClassLoader().getResources("/messages/apps.properties");

答案 1 :(得分:2)

看看这个优秀的article关于springpath加载的classpath v classpth *差异,我在测试中对你的问题进行了一些测试,无论我使用classpath还是classpath *

我在这里列出了关于我做过的测试的代码

  • 我创建了一个这个目录结构(在src / main / resource下的META-INF / spring)放置了context.xml
  • 我在这里列出了完整的context.xml

       <?xml version="1.0" encoding="UTF-8"?>
         <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="http://www.springframework.org/schema/beans                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
       <bean id="propertyPlaceholderConfigurer"
                 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:messages/apps.properties</value>
            </list>
        </property>
      </bean>
    
        <bean class="prasanna.service.TestBean">
           <property name="appName" value="${appname}"></property>
         </bean>
    
    <bean id="messageSource"  class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
         <list>
           <value>classpath:messages/ValidationMessages</value>
               <value>classpath:messages/apps</value>
           </list>
       </property>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>
        </beans>
    
  • 列出apps.properties

     appname=spring mvc app
    
  • 列出ValidationMessages.properties

      error.name=Invalid name
    
  • TestBean相当简单

        public class TestBean 
        {
            private String appName;
    
            public String getAppName() {
                return appName;
            }
    
            public void setAppName(String appName) {
                this.appName = appName;
            }
    
        }
    
  • 我使用一个简单的java类来加载属性文件并读取它们

    public class LoadContext 
    {
        public static void main(String[] args) 
        {
            ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:META-INF/spring/context.xml"});
            ReloadableResourceBundleMessageSource msgs = ctx.getBean(ReloadableResourceBundleMessageSource.class);
    
                  TestBean testBean = ctx.getBean(TestBean.class);
        Assert.assertTrue(testBean.getAppName().equals("spring mvc app"));
    
            String msg = msgs.getMessage("appname", new Object[]{new DefaultMessageSourceResolvable("appname")}, null);
            System.out.println(" "+ msg);
    
            String msg2 = msgs.getMessage("error.name", new Object[]{new DefaultMessageSourceResolvable("error.name")}, null);
            System.out.println(" "+ msg2);
        }
    
    }