JSF 2.0 中 Application#getResourceBundle() 和 ResourceBundle#getBundle() 之间的区别

2023-12-08

为了从资源包中检索字符串,我尝试比较这两种方法的结果,下面是代码示例:

第一个例子:

baseName:资源包的完全限定名称(<base-name> in <resource-bundle>).

FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
ResourceBundle bundle = app.getResourceBundle(context, baseName);

第二个例子:

varName:是代表的字符串<var></var> in <resource-bundle>

FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context .getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(varName, locale, loader);

这两个例子有什么区别?如果没有区别,获取 ResourceBundle 的最佳实践是什么(使用 Application#getMessageBundle() 或 ResourceBundle#getBundle())?


首先,您混淆了方法的 varName/baseName。实际的做法是:

Application#getResourceBundle()

varName: 是代表的字符串<resource-bundle><var> in faces-config.xml

FacesContext context = FacesContext.getCurrentInstance();
Application application = context.getApplication();
ResourceBundle bundle = application.getResourceBundle(context, varName);

ResourceBundle#getBundle()

baseName: 是资源包的完全限定名称,例如<resource-bundle><base-name>

FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context.getViewRoot().getLocale();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale, loader);

前者通过JSF获取Application,这也会在幕后使用UIViewRoot#getLocale()(后备至Locale#getDefault()),而后者则直接获取。

至于技术和最终结果,没有区别。在这两种情况下,您将获得完全相同的捆绑包(前提是区域设置正确)。但是,就可维护性而言,肯定是不同的。资源包属于“配置”,并且必须外部化(在faces-config.xml).

对 FQN 进行硬编码,如下所示baseName这是一个糟糕的做法。如果不重新编译和重建所有代码,您无法轻松快速更改 FQN。如果是在第3方的JAR文件中,那就更麻烦了。否则你可以用另一个覆盖它<resource-bundle>在同一<var>从你的网络应用程序内部。此外,JSF 组件/实用程序库可能提供自己的Application可以装饰的包装纸getResourceBundle()打电话来做一些令人敬畏的事情。如果您直接通过获取它,这是不可能的ResourceBundle#getBundle().


顺便说一句,还有第三种方法:直接注入。

在 JSF 托管 bean 中,提供了<var>text</var>:

@ManagedProperty("#{text}")
private ResourceBundle text;

或者在 CDI 托管 bean 中:

@Inject
private PropertyResourceBundle text;

与这位制作人:

public class BundleProducer {

    @Produces
    public PropertyResourceBundle getBundle() {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{text}", PropertyResourceBundle.class);
    }

}

注:EL评估#{text}捆绑使用的幕后用途Application#getResourceBundle().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSF 2.0 中 Application#getResourceBundle() 和 ResourceBundle#getBundle() 之间的区别 的相关文章

随机推荐