Webwork2.2.6 源码解读之Configuration

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

在init方法中,DispatcherUtils.initialize(getServletContext())的调用完成了配置文件的读取、ObjectFactory的设置(也是根据配置文件)。类Configuration充当了读取配置文件的功能。其子类包括:
[img]http://dl.iteye.com/upload/attachment/234170/601e6782-7028-3470-8d77-29f6c227e138.jpg[/img]
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;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值