JSF国际化f:loadbundle或通过faces-config: Performance point



有两种方法将属性文件加载到JSF 2.0中。

  1. 全局资源包全局加载属性文件,以便所有jsf页面都可以访问消息。你可以创建一个"faces-config.xml"文件,并显式地声明属性文件。

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
    version="2.0">
     <application>
      <resource-bundle>
        <base-name>com.mkyong.messages</base-name>
        <var>msg</var>
       </resource-bundle>
     </application>
</faces-config>

选项2:本地资源包本地加载属性文件,或仅为指定页面加载属性文件。在messages.properties中声明需要访问消息的页面中的<f:loadBundle />标记。

这两个中哪一个给我更好的表现?

假设我选择第一个选项,这意味着所有的bundle在应用程序启动时被加载还是延迟加载?(按需)

如果选择第二个选项,它是否可能导致bundle为每个viewwroot加载多次?

是Java ResourceBundle是工厂类,在servlet容器内提供单例对象?

我的意思是getBundle方法是工厂方法,它总是创建单例对象?

ResourceBundle myResources =
      ResourceBundle.getBundle("MyResources", currentLocale);

假设我有一个页面abc.xhtml,我使用f:loadBundle,有1000个用户访问这个页面,这是否意味着将有1000个资源bundle对象创建?或者它是所有页面实例共享的唯一对象?

这两个中哪一个给我更好的表现?

我不会担心表演。ResourceBundle已经在内部缓存它们。


假设我有一个页面abc.xhtml,我使用f:loadBundle,有1000个用户访问这个页面,这是否意味着有1000个resouceBundle对象创建?或者它是所有页面实例共享的唯一对象?

缺省情况下,只创建一个。参见ResourceBundle API文档:

缓存管理

由getBundle工厂方法创建的资源束实例默认情况下被缓存,并且工厂方法多次返回相同的资源束实例,如果它已被缓存。getBundle客户端可以清除缓存,使用生存时间值管理缓存的资源束实例的生命周期,或者指定不缓存资源束实例。参考getBundle工厂方法、clearCacheResourceBundle.Control.getTimeToLiveResourceBundle.Control.needsReload的描述

你可以通过查看实例的hashcode在调试器中轻松地验证。


顺便说一下,<application>声明还有一个额外的好处,即该包也可以通过@ManagedProperty("#{msg}")注入到托管bean中。

从答案中可以看出,一个全局资源包就足够了。在性能:

有两种标准的ResourceBundle实例:

  • PropertyResourceBundle - *[_LOCALE]。属性文件和
  • ListResourceBundle,一个java类(使用带有'.'的包名)- *[_LOCALE].class.
ListResourceBundle

:

每个locale java类创建一个字符串数组,其中包含共享(!)键和本地化文本。在JVM中共享键字符串很好。而且所有的字符串都是提前加载的。

所以交付一个ListResourceBundle可能是值得的。

但是,对于翻译,您可能需要维护一些非java翻译内存,如tmx、xliff等。并在构建过程中生成java.

第一个选项-因为它是应用程序范围,并且在启动时加载

相关内容

  • 没有找到相关文章

最新更新