struts国际化研究(二)——工厂模式

 

抽象工厂模式

      在struts国际化研究(一)中介绍了struts的默认国际化的默认实现类,但是在国际化的过程中,大多方法使用是MessageResources类中的方法,这里就是struts国际化的核心。

 

      抽象工厂模式定义:提供一个接口,用于创建相关或依赖的对象家族,而不需要指定具体类。

 

      MessageResources是一个抽象类(特殊的接口),其中仅有一个抽象方法public abstract String getMessage(Locale locale, String key),这个正式国际化的入口。

      PropertyMessageResources(struts默认国际化类)继承MessageResources并实现的getMessage(Locale locale, String key)方法,当然自定义的国际化类也实现该接口,从而形成国际化文件家族。

 

    public String getMessage(Locale locale, String key) {

        if (log.isDebugEnabled()) {
            log.debug("getMessage(" + locale + "," + key + ")");
        }

        // Initialize variables we will require
        String localeKey = localeKey(locale);
        String originalKey = messageKey(localeKey, key);
        String messageKey = null;
        String message = null;
        int underscore = 0;
        boolean addIt = false;  // Add if not found under the original key

        // Loop from specific to general Locales looking for this message
        while (true) {

            // Load this Locale's messages if we have not done so yet
            loadLocale(localeKey);

            // Check if we have this key for the current locale key
            messageKey = messageKey(localeKey, key);
            synchronized (messages) {
                message = (String) messages.get(messageKey);
                if (message != null) {
                    if (addIt) {
                        messages.put(originalKey, message);
                    }
                    return (message);
                }
            }

            // Strip trailing modifiers to try a more general locale key
            addIt = true;
            underscore = localeKey.lastIndexOf("_");
            if (underscore < 0) {
                break;
            }
            localeKey = localeKey.substring(0, underscore);

        }

        // Try the default locale if the current locale is different
        if (!defaultLocale.equals(locale)) {
            localeKey = localeKey(defaultLocale);
            messageKey = messageKey(localeKey, key);
            loadLocale(localeKey);
            synchronized (messages) {
                message = (String) messages.get(messageKey);
                if (message != null) {
                    messages.put(originalKey, message);
                    return (message);
                }
            }
        }

        // As a last resort, try the default Locale
        localeKey = "";
        messageKey = messageKey(localeKey, key);
        loadLocale(localeKey);
        synchronized (messages) {
            message = (String) messages.get(messageKey);
            if (message != null) {
                messages.put(originalKey, message);
                return (message);
            }
        }

        // Return an appropriate error indication
        if (returnNull) {
            return (null);
        } else {
            return ("???" + messageKey(locale, key) + "???");
        }

    }
 

 

 

工厂方法模式

工厂方法模式:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

 

      struts的工厂类MessageResourcesFactory,他是一个抽象类,包含一个抽象方法public abstract MessageResources createResources(String config),它的作用正如起名创建资源,怎么创建?看默认实现类。

      MessageResourcesFactory的factoryClass指定了默认实现类PropertyMessageResourcesFactory

protected static String factoryClass = "org.apache.struts.util.PropertyMessageResourcesFactory";

PropertyMessageResourcesFactory很简单,就一个方法

 

    public MessageResources createResources(String config) {

        return new PropertyMessageResources(this, config, this.returnNull);

    }
 

 

 

 

现在看一下struts是如何运用这个工程类创建MessageResources

struts的核心加载类是ActionServlet,他的initModuleMessageResources(ModuleConfig config)方法对国际化类进行初始化

 

    protected void initModuleMessageResources(ModuleConfig config)
        throws ServletException {

        MessageResourcesConfig mrcs[] = config.findMessageResourcesConfigs();
        for (int i = 0; i < mrcs.length; i++) {
            if ((mrcs[i].getFactory() == null)
                || (mrcs[i].getParameter() == null)) {
                continue;
            }
            if (log.isDebugEnabled()) {
                log.debug(
                    "Initializing module path '"
                        + config.getPrefix()
                        + "' message resources from '"
                        + mrcs[i].getParameter()
                        + "'");
            }

            // 读取struts-config.xml中message-resources的属性
            String factory = mrcs[i].getFactory();
            // 该方法将覆盖factoryClass值(factoryClass上文中提到,工厂初始化类路径)
            MessageResourcesFactory.setFactoryClass(factory);
            // 调用createResources方法了,默认使用的是PropertyMessageResourcesFactory的,如果在struts-config.xml中定义了工厂类,这里将使用用户自定义的创建方法
            MessageResourcesFactory factoryObject =
                MessageResourcesFactory.createFactory();
            factoryObject.setConfig(mrcs[i]);

            // 通过factory创建MessageResources后,设置基本属性,这些属性是抽象工厂创建国际化家族所需的基本属性
            MessageResources resources =
                factoryObject.createResources(mrcs[i].getParameter());
            resources.setReturnNull(mrcs[i].getNull());
            resources.setEscape(mrcs[i].isEscape());
            getServletContext().setAttribute(
                mrcs[i].getKey() + config.getPrefix(),
                resources);
        }

    }

      这里还有一个实现细节需要注意PropertyMessageResourcesFactory的createResources方法在创建MessageResources的同时,将自己注入到了新创建的MesageResources中 ,MessageResources可以通过getFactory()方法轻松获取工厂类。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值