简体   繁体   English

JSF国际化f:loadbundle或通过faces-config:性能点

[英]JSF Internationalization f:loadbundle or through faces-config: Performance point

There are two ways to load the properties file into JSF 2.0. 有两种方法可以将属性文件加载到JSF 2.0中。

  1. Global Resource Bundle To load the properties file globally, so that all the jsf pages can access the messages. 全局资源包要全局加载属性文件,以便所有jsf页都可以访问消息。 You can create a “faces-config.xml” file and declare the properties file explicitly. 您可以创建“faces-config.xml”文件并显式声明属性文件。

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>

Option 2: Local Resource Bundle To load the properties file locally, or for specified page only. 选项2:本地资源包在本地或仅为指定页面加载属性文件。 Declare the <f:loadBundle /> tag in the page that need to access the message in the messages.properties. 在需要访问messages.properties中的消息的页面中声明<f:loadBundle />标记。

Out of these two which one gives me better performance? 在这两个中哪一个给了我更好的表现?

Lets say I going with 1st option, does it means all the bundles gets loaded during the application startup or is it lazy loading? 假设我使用第一个选项,是否意味着在应用程序启动期间所有捆绑包都被加载或是否是延迟加载? (on demand) (一经请求)

If choose a 2nd option, does it potentially cause bundle to get loaded multiple time for each ViewRoot? 如果选择第二个选项,是否可能导致每个ViewRoot多次加载bundle?

Is the Java ResourceBundle is factory class which provides singleton object within servlet container? Java ResourceBundle是工厂类,它在servlet容器中提供单例对象吗?

I mean getBundle method is factory method which creates singleton object for always? 我的意思是getBundle方法是工厂方法,它总是创建单独的对象?

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

Lets say I have a page abc.xhtml and I am using f:loadBundle, and there 1000 users accessing this page, does this mean there would 1000 resouceBundle object created? 假设我有一个页面abc.xhtml,我使用的是f:loadBundle,有1000个用户访问此页面,这是否意味着会创建1000个resouceBundle对象? or is it only object which is being shared by all the page instances? 或者它只是所有页面实例共享的对象?

Out of these two which one gives me better performance? 在这两个中哪一个给了我更好的表现?

I wouldn't worry about the performance. 我不担心性能。 The ResourceBundle already caches them internally. ResourceBundle已经在内部缓存它们。


Lets say I have a page abc.xhtml and I am using f:loadBundle, and there 1000 users accessing this page, does this mean there would 1000 resouceBundle object created? 假设我有一个页面abc.xhtml,我使用的是f:loadBundle,有1000个用户访问此页面,这是否意味着会创建1000个resouceBundle对象? or is it only object which is being shared by all the page instances? 或者它只是所有页面实例共享的对象?

By default, only one is created. 默认情况下,只创建一个。 See also the ResourceBundle API documentation : 另请参阅ResourceBundle API文档

Cache Management 缓存管理

Resource bundle instances created by the getBundle factory methods are cached by default, and the factory methods return the same resource bundle instance multiple times if it has been cached. 默认情况下,getBundle工厂方法创建的资源包实例会被缓存,如果已缓存,则工厂方法会多次返回相同的资源包实例。 getBundle clients may clear the cache, manage the lifetime of cached resource bundle instances using time-to-live values, or specify not to cache resource bundle instances. getBundle客户端可以清除缓存,使用生存时间值管理缓存资源包实例的生命周期,或指定不缓存资源包实例。 Refer to the descriptions of the getBundle factory method , clearCache , ResourceBundle.Control.getTimeToLive , and ResourceBundle.Control.needsReload for details. 有关详细信息,请参阅getBundle工厂方法clearCacheResourceBundle.Control.getTimeToLiveResourceBundle.Control.needsReload的说明。

You can easily testify if yourself in debugger by looking at instance's hashcode. 通过查看实例的哈希码,您可以轻松地在调试器中证明自己。


The <application> declaration has by the way the additional benefit that the bundle is also injectable in a managed bean by @ManagedProperty("#{msg}") . 顺便提一下, <application>声明还有一个额外的好处,即@ManagedProperty("#{msg}")也可以在托管bean中注入bundle。 See also among others this Q&A: Read resource bundle properties in a managed bean . 另请参阅此问答: 在托管bean中读取资源包属性

You have seen from the answers that one global resource bundle suffices. 您已经从答案中看到一个全局资源包就足够了。 On performance: 关于表现:

You have two kind of standard ResourceBundle instances: 您有两种标准的Res​​ourceBundle实例:

  • PropertyResourceBundle - *[_LOCALE].properties files, and PropertyResourceBundle - * [_ LOCALE] .properties文件,和
  • ListResourceBundle, a java class (using package names with '.') - *[_LOCALE].class. ListResourceBundle,一个java类(使用带有'。'的包名) - * [_ LOCALE] .class。

For ListResourceBundle: 对于ListResourceBundle:

Every locale java class creates an array of strings with shared (!) key and localized text. 每个语言环境java类都创建一个包含共享(!)键和本地化文本的字符串数组。 Sharing the key strings in the JVM is nice. 在JVM中共享密钥字符串很不错。 Also all strings are loaded early. 所有字符串都会尽早加载。

So it might be worth delivering a ListResourceBundle. 所以可能值得提供一个ListResourceBundle。

For translation however, you then probably would have to maintain some non-java translation memory, tmx, xliff or so. 但是,对于翻译,您可能需要维护一些非java翻译记忆库,tmx,xliff等。 And in the build process generate the java. 并在构建过程中生成java。

第一个选项 - 因为它是应用程序作用域并在启动时加载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM