首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

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

2012-07-04 
struts国际化研究(二)——工厂模式?抽象工厂模式? ? ? 在struts国际化研究(一)中介绍了struts的默认国际化的

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()方法轻松获取工厂类。

?

?

热点排行