`
somebody_hjh
  • 浏览: 180979 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Webwork2.2.6 源码解读之Configuration

    博客分类:
  • Java
阅读更多

在webwork2.2.6版本中,不管是用ServletDispatcher还是FilterDispatcher充当请求转发器(可在web.xml中配置),都会调用到相关Servlet的init或Filter的init方法。

在init方法中,DispatcherUtils.initialize(getServletContext())的调用完成了配置文件的读取、ObjectFactory的设置(也是根据配置文件)。类Configuration充当了读取配置文件的功能。其子类包括:

webwork提供了默认资源文件类型、property资源文件类型,还有DelegatingConfiguration资源文件类型 ,你也可以实现自己的XMLConnfiguration。
查看Configuration类代码,我们可以看到非静态方法,包括isSetImpl(String name)直接返回false,setImpl(String name, Object value)直接抛出异常,这是一种变态的abstract类设计,在需要使用该类的静态方法,却又不愿意调用者实例化该类并调用非静态方法时候,用这种变通的做法也是不错的选择。(因为我们不能同时让static和abstract修饰一个类)。

另外,该做法实现了多态,在这种多态中,子类可以被任意更换,确只保证只有一个之类实例存在。实现方法是在Configuration中建立静态变量static Configuration configurationImpl;调用端可以通过实例化不同的子类赋予configurationImpl。最后通过Configuration.getConfiguration() 获取唯一的实例。


这样的设计在webwork其他地方也经常可见。如ActionProxyFactory及其子类,但是不同的是ActionProxyFactory是absctract的,因为ActionProxyFactory没有设计有静态方法。


这种设计在策略互换且只允许单个策略的情况下相当有用,今天看了这段代码,且做一个笔记。

代码如下:::
public class Configuration {

    static Configuration configurationImpl;
    static Configuration defaultImpl;
    static Locale locale; // Cached locale
    private static final Log LOG = LogFactory.getLog(Configuration.class);


    /**
     * Sets the current configuration implementation. Can only be called once.
     *
     * @param config a Configuration implementation
     * @throws IllegalStateException if an error occurs when setting the configuration implementation.
     */
    public static void setConfiguration(Configuration config) throws IllegalStateException {
        configurationImpl = config;
        locale = null; // Reset cached locale
    }

    /**
     * Gets the current configuration implementation.
     *
     * @return the current configuration implementation.
     */
    public static Configuration getConfiguration() {
        return (configurationImpl == null) ? getDefaultConfiguration() : configurationImpl;
    }

    /**
     * Returns the WebWork2 locale. Keys off the property <tt>webwork.locale</tt> which should be set
     * as the Java {@link java.util.Locale#toString() toString()} representation of a Locale object (i.e.,
     * "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr_MAC", etc). <p>
     * <p/>
     * If no locale is specified then the default VM locale is used ({@link java.util.Locale#getDefault()}).
     *
     * @return the WebWork2 locale if specified or the VM default locale.
     */
    public static Locale getLocale() {
        if (locale == null) {
            try {
                StringTokenizer localeTokens = new StringTokenizer(getString(WebWorkConstants.WEBWORK_LOCALE), "_");
                String lang = null;
                String country = null;

                if (localeTokens.hasMoreTokens()) {
                    lang = localeTokens.nextToken();
                }

                if (localeTokens.hasMoreTokens()) {
                    country = localeTokens.nextToken();
                }

                locale = new Locale(lang, country);
            } catch (Throwable t) {
                // Default
                LOG.warn("Setting locale to the default locale");
                locale = Locale.getDefault();
            }
        }

        return locale;
    }

    /**
     * Determines whether or not a value has been set. Useful for testing for the existance of parameter without
     * throwing an IllegalArgumentException.
     *
     * @param name the name of the property to test.
     * @return <tt>true</tt> if the property exists and has a value, <tt>false</tt> otherwise.
     */
    public static boolean isSet(String name) {
        return getConfiguration().isSetImpl(name);
    }

    /**
     * Returns a property as a String. This will throw an <tt>IllegalArgumentException</tt> if an error occurs
     * while retrieveing the property or if the property doesn't exist.
     *
     * @param name the name of the property to get.
     * @return the property as a String
     * @throws IllegalArgumentException if an error occurs retrieveing the property or the property does not exist.
     */
    public static String getString(String name) throws IllegalArgumentException {
        String val = get(name).toString();

        return val;
    }

    /**
     * Returns a property as an Object. This will throw an <tt>IllegalArgumentException</tt> if an error occurs
     * while retrieveing the property or if the property doesn't exist.
     *
     * @param name the name of the property to get.
     * @return the property as an Object.
     * @throws IllegalArgumentException if an error occurs retrieveing the property or the property does not exist.
     */
    public static Object get(String name) throws IllegalArgumentException {
        Object val = getConfiguration().getImpl(name);

        return val;
    }

    /**
     * Returns an Iterator of all properties names.
     *
     * @return an Iterator of all properties names.
     */
    public static Iterator list() {
        return getConfiguration().listImpl();
    }

    /**
     * Implementation of the {@link #isSet(String)} method.
     *
     * @see #isSet(String)
     */
    public boolean isSetImpl(String name) {
        // this is dumb.. maybe it should just throw an unsupported op like the rest of the *Impl
        // methods in this class.
        return false;
    }

    /**
     * Sets a property. Throws an exception if an error occurs when setting the property or if the
     * Configuration implementation does not support setting properties.
     *
     * @param name  the name of the property to set.
     * @param value the property to set.
     * @throws IllegalArgumentException      if an error occurs when setting the property.
     * @throws UnsupportedOperationException if the config implementation does not support setting properties.
     */
    public static void set(String name, Object value) throws IllegalArgumentException, UnsupportedOperationException {
        getConfiguration().setImpl(name, value);
    }

    /**
     * Implementation of the {@link #set(String, Object)} method.
     *
     * @see #set(String, Object)
     */
    public void setImpl(String name, Object value) throws IllegalArgumentException, UnsupportedOperationException {
        throw new UnsupportedOperationException("This configuration does not support updating a setting");
    }

    /**
     * Implementation of the {@link #get(String)} method.
     *
     * @see #get(String)
     */
    public Object getImpl(String aName) throws IllegalArgumentException {
        return null;
    }

    /**
     * Implementation of the {@link #list()} method.
     *
     * @see #list()
     */
    public Iterator listImpl() {
        throw new UnsupportedOperationException("This configuration does not support listing the settings");
    }

    private static Configuration getDefaultConfiguration() {
        if (defaultImpl == null) {
            // Create bootstrap implementation
            defaultImpl = new DefaultConfiguration();

            // Create default implementation
            try {
                String className = getString(WebWorkConstants.WEBWORK_CONFIGURATION);

                if (!className.equals(defaultImpl.getClass().getName())) {
                    try {
                        // singleton instances shouldn't be built accessing request or session-specific context data
                        defaultImpl = (Configuration) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className), null);
                    } catch (Exception e) {
                        LOG.error("Could not instantiate configuration", e);
                    }
                }
            } catch (IllegalArgumentException ex) {
                // ignore
            }
        }

        return defaultImpl;
    }

    public static void reset() {
        defaultImpl = null;
        configurationImpl = null;
    }
}


  • 大小: 22.2 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics