1. 在xml中配置你的properties路径:

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

<property name="basenames">

<list> <!-- 指定资源文件基名称 jdbc为文件名,不包含扩展名 -->

<value>classpath:resource/jdbc</value>

</list>

</property>

</bean>

2. 获取WebApplicationContext(需要入参HttpServletRequest request) ServletContext servletContext = request.getSession() .getServletContext(); WebApplicationContext ctx = WebApplicationContextUtils .getRequiredWebApplicationContext(servletContext);

3. 通过WebApplicationContext获取中键值 String msg = ctx.getMessage("jdbc.url", null, Locale.CHINA);

----------------------------------------------------------------------------------------------------------------

Spring的MessageSource有两个常用的实现ReloadableResourceBundleMessageSourceResourceBundleMessageSource。这两个类在配置上有些区别。
 
我原来常用ResourceBundleMessageSource,它的典型配置如下:
 
        <bean id="messageSource" 
               class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
                <property name="parentMessageSource" ref="bizMessageSource"/> 
                <property name="basenames"> 
                        <list> 
                                <value>resources.cls-web-resources</value> 
                                <value>resources.cls-web-resources-definitions</value> 
                                <value>resources.cls-web-resources-menu</value>
                        </list> 
                </property> 
        </bean>
 
在比较一下ReloadableResourceBundleMessageSource的配置:
<bean id="messageSource" 
               class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
                <property name="parentMessageSource" ref="bizMessageSource"/> 
                <property name="fallbackToSystemLocale"><value>false</value></property> 
                <property name="basenames"> 
                        <list> 
                                <value>classpath:resources/cls-web-resources</value> 
                                <value>classpath:resources/cls-web-resources-definitions</value> 
                                <value>classpath:resources/cls-web-resources-menu</value>  
                        </list> 
                </property> 
        </bean>
 
原因在于ReloadableResourceBundleMessageSource的内部使用DefaultResourceLoader来装载ResourceBundle,而ResourceBundleMessageSource内部是直接使用java.util.ResourceBundle.getBundle(String baseName,Locale locale, ClassLoader loader) 来获取i18n文件信息的,而ResourceBundle是使用“.”来作为basename分隔符的(这也是我们常用的形式),所以很前面的配置有些区别。
 
另外如果你不设置“fallbackToSystemLocale”的话,那么当你传入的Locale是null或者ResourceBundle没有该Locale的配置文件的话,那么会返回Locale.getDefault()的Locale下的Message。该设置默认为True,也就是说,如果找不到相应的ResourceBundle,系统始终会显示为中文的Resource,建议关掉该设置,否则fallBackLocale久没有什么意义了
 
另外还有一个有用的设置“useCodeAsDefaultMessage”,默认为false,这样当Spring在ResourceBundle中找不到messageKey的话,就抛出NoSuchMessageException,把它设置为True,则找不到不会抛出异常,而是使用messageKey作为返回值。
----------------------------------------------------------------------------------
spring中ResourceBundleMessageSource与ReloadableResourceBundleMessageSource查找资源的区别:

1.ResourceBundleMessageSource在xml配置中无法指定编码:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

<property name="basenames">

<list>

<value >error</value >

<value >message</value >

</list>

</property>

</bean>

而ReloadableResourceBundleMessageSource可以指定编码,譬如:

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

<property name="defaultEncoding" value ="gbk" />

<property name="basename" value ="message" />

</bean>

2.加载资源文件的方式不同:

1).下面看下它们的源代码:

ResourceBundleMessageSource的加载,使用ClassUtils.getDefaultClassLoader()加载器,getDefaultClassLoader的方法代码如下:

p lic static ClassLoader getDefaultClassLoader()

{

ClassLoader cl = null;

try {

cl = Thread.currentThread().getContextClassLoader();

}

catch (Throwable ex) {

logger.debug("Cannot access thread context ClassLoader - falling back to system class loader", ex);

}

if (cl == null)

{

cl = ClassUtils.class.getClassLoader();

}

return cl;

}

//这种方式也是JVM默认的加载方式,先从当前线程中获取类加载器,如果没有,就获取这个类本身的类加载器

2).ReloadableResourceBundleMessageSource默认也使用ClassUtils.getDefaultClassLoader()加载器,它加载资源的方式如下:

p lic Resource getResource(String location)

{

Assert.notNull(location, "Location must not be null");

if (location.startsWith("classpath:")) {

return new ClassPathResource(location.s string("classpath:".length()), getClassLoader());

}

try

{

URL url = new URL(location);

return new UrlResource(url);

}

catch (MalformedURLException ex)

{

return getResourceByPath(location);

}

}

3). 小结:ResourceBundleMessageSource从classloader中加载资源文件,可以找到,

ReloadableResourceBundleMessageSource加载时,默认使用DefaultResourceLoader,他会先判断资源path是否带有classpath:前缀,如果有,用 ClassPathResource去加载资源文件,如果没有试着用文件协议的url去访问,再没有就在contextPath即WEB-INF下查找。

下面做一个Spring的MessageSource的示例:

1.我们单独新建一个spring消息文件beans-message.xml中加如下配置:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

<property name="basenames">

<list>

<value >error</value>

<value >message</value >

</list>

</property>

</bean>

2.这段配置假定在你的classpath中有两个资源文件(resource bundle),它们是error, message。通过ResourceBundle,使用JDK中解析消息的标准方式,来处理任何解析消息的请求。出于示例的目的,假定 message_zh_CN.properties的资源文件的内容为…

msg.common.serverBusy = \非\常\抱\歉,\系\统\十\分\繁\忙\!

#非常抱歉,系统十分繁忙!

msg.argument.required={0}\是\个\必\填\项\!

#{0}是个必填项!

3.再写一个测试类:

p lic class MessageTest {

p lic static void main(String[] args) {

MessageSource resources = new ClassPathXmlApplicationContext("beans-message.xml");

String message = resources.getMessage("msg.common.serverBusy", null, "Default", null);

System.out.println(message);

String message1 = resources.getMessage("msg.argument.required", new Object[] { "'联系方式'" }, null, Locale.CHINA);

System.out.println(message1);

}

}

结果输入为:

非常抱歉,系统十分繁忙!

'联系方式'是个必填项!

3.在我们的项目中,MessageSource不会单独使用,通常我们会把它和自己的业务一起使用,这时候我们可以直接用它本身的方法,我们也可以在其中加入我们自己的逻辑:如,自定义的一个消息类:

p lic class MessageSourceHelper {

private ResourceBundleMessageSource messageSource;

p lic String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {

String msg = messageSource.getMessage(code, args, defaultMessage, locale);

return msg != null ? msg.trim() : msg;

}

p lic void setMessageSource(ResourceBundleMessageSource messageSource) {

this.messageSource = messageSource;

}

}

在beans-message.xml中注入:

<bean id="messageSourceHelper" class="com.myspring.message.MessageSourceHelper">

<property name="messageSource">

<ref local="messageSource" />

</property>

</bean>

4.我们可以在MessageSourceHelper中加入自己的业务,注入依赖后,就可以在其他类中调用MessageSourceHelper中的方法。

5.理论简要:ApplicationContext接口扩展了MessageSource 接口,因而提供了消息处理的功能(i18n或者国际化)。与HierarchicalMessageSource一起使用,它还能够处理嵌套的消息,这些是Spring提供的处理消息的基本接口。让我们快速浏览一下它所定义的方法:

· String getMessage(String code, Object[] args, String default, Locale loc):用来从MessageSource获取消息的基本方法。如果在指定的locale中没有找到消息,则使用默认的消息。args中的参数将使用标准类库中的MessageFormat来作消息中替换值。

· String getMessage(String code, Object[] args, Locale loc):本质上和上一个方法相同,其区别在:没有指定默认值,如果没找到消息,会抛出一个NoS hMessageException异常。

· String getMessage(MessageSourceResolvable resolvable, Locale locale):上面方法中所使用的属性都封装到一个MessageSourceResolvable实现中,而本方法可以指定 MessageSourceResolvable实现。

当一个ApplicationContext被加载时,它会自动在context中查找已定义为MessageSource类型的bean。此bean的名称须为messageSource。如果找到,那么所有对上述方法的调用将被委托给该 bean。否则ApplicationContext会在其父类中查找是否含有同名的bean。如果有,就把它作为MessageSource。如果它最终没有找到任何的消息源,一个空的StaticMessageSource将会被实例化,使它能够接受上述方法的调用。

Spring目前提供了两个MessageSource的实现:ResourceBundleMessageSource和StaticMessageSource。它们都继承 NestingMessageSource以便能够处理嵌套的消息。StaticMessageSource很少被使用,但能以编程的方式向消息源添加消息。ResourceBundleMessageSource会用得更多一些

spring 如何动态加载properties文件的内容的更多相关文章

  1. Spring -09 -在Spring工程 中加载 properties 文件 -为某个属性添加注解赋初值

    1.在src 下新建 xxx.properties 文件,不要任意加空格,注明jdbc等标识名!2.在spring 配置文件中先引入xmlns:context,在下面添加2.1如果需要记载多个配置文件 ...

  2. spring配置数据源(加载properties文件)

    1.在spring中引入properties配置文件需要引入context的命名空间和真实地址 2.然后加载文件 需要注意的是这是采用的是set注入方式,所以name属性值必须是连接池set方法名去掉 ...

  3. Spring加载properties文件的属性的值

    要使用配置文件的值首先在spring.xml配置加载properties文件 <context:property-placeholder location="classpath:ife ...

  4. 不停服务,动态加载properties资源文件

    系统运行过程中,我们用注解@Value("${****}")可以获取资源文件中的内 容,获取的内容会被存储在spring缓存中,因此如果我们修改了资源文件,要 想读取到修改后的内容 ...

  5. spring入门(二)【加载properties文件】

    在开发过程当中需要用到配置信息,这些信息不能进行硬编码,这时配置文件是一个比较好的方式,java提供了properties格式的文件,以键值对的方式保存信息,在读取的时候通过键获得键对应的值,spri ...

  6. Spring加载properties文件的两种方式

    在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可, ...

  7. Java_Java中动态加载jar文件和class文件

    转自:http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下 ...

  8. [转载] Java中动态加载jar文件和class文件

    转载自http://blog.csdn.net/mousebaby808/article/details/31788325 概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下 ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件

    一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...

随机推荐

  1. Android学习总结(二)——Service基本概念和生命周期

    好了,前面我们已经学习了Activity的知识,相信大家也有一定的理解,但是还是不能放松,Android四大组件,我们才学习了一个而已,接下我们继续学习Service.计划总结如下内容: 一.Serv ...

  2. 使用javap分析Java的字符串操作

    我们看这样一行简单的字符串赋值操作的Java代码. String a = "i042416"; 使用命令行将包含了这行代码的Java类反编译查看其字节码: javap -v con ...

  3. iOS 随机数(Fixed)

    ios 有如下三种随机数方法: 1.    srand((unsigned)time(0));  //不加这句每次产生的随机数不变         int i = rand() % 5; 2.     ...

  4. ftpaccess - ftpd的配置档

    描述 DESCRIPTION 这个ftpaccess档案是用来配置下述功能的运作 存取功能(AccessCapabilities) autogroup<群组名称><类别>[&l ...

  5. javascript设计模式(张容铭)学习笔记 - 照猫画虎-模板方法模式

    模板方法模式(Template Method):父类中定义一组操作算法骨架,而降一些实现步骤延迟到子类中,使得子类可以不改变父类的算法结构的同时可重新定义算法中某些实现步骤. 项目经理体验了各个页面的 ...

  6. javascript设计模式(张容铭) 第14章 超值午餐-组合模式 学习笔记

    JS 组合模式更常用于创建表单上,比如注册页面可能有不同的表单提交模块.对于这些需求我们只需要有基本的个体,然后通过一定的组合即可实现,比如下面这个页面样式(如图14-2所示),我们来用组合模式实现. ...

  7. 删除链表的倒数第N个节点(三种方法实现)

    删除链表的倒数第N个节点 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒 ...

  8. 暴力解说之首次部署NGINX

    前言 本章基于Centos 7.x系统讲解 本章讲解下在项目上线部署的时候对NGINX的操作.有些童鞋在网上百度类似LNMP安装就跟着命令一条一条执行了,如果没报错还好,一旦报错就懵逼状态了.这是对自 ...

  9. PyQt5(2)、垃圾分类小程序(2)——初代窗口程序可执行文件

    又是一天时间(又没做大作业).今天的心路历程:(1)前端后端怎么连接?(2)后端数据库插数据(3)完全没用上之前的字典反查法(4)突然发现面向对象编程其实很好用,甚至越用越上瘾(5)QLineEdit ...

  10. Codeforces Round #439 (Div. 2) E. The Untended Antiquity

    E. The Untended Antiquity 题目链接http://codeforces.com/contest/869/problem/E 解题心得: 1.1,x1,y1,x2,y2 以(x1 ...