Webwork 学习之路(四)Configuration 详解

阅读目录

  Webwork做为经典的Web MVC 框架,个人觉得源码中配置文件这部分代码的实现十分考究。

  支持自定义自己的配置文件、自定义配置文件读取类、自定义国际化支持。

  可以作为参考,单独引入到其他项目中,下面是Configuration相关类的继承关系:

 

 

回到顶部

1. Configuration

  • Configuration 作为 webwork 配置文件的核心类,起到了配置信息读取的门户,默认实现类中间引入了代理类 DelegatingConfiguration 与底层的具体实现读取的 PropertiesConfiguration 完全解耦。在项目中使用时,只需要引入 Configuration 类,如下代码即可获取配置信息;

Configuration.getString("webwork.locale")
  • getString 方法会调用 Configuration 自身的get 方法,get 方法中调用 getConfiguration 方法:

1     public static String getString(String name) throws IllegalArgumentException {
2         String val = get(name).toString();
3         return val;
4     }

1     public static Object get(String name) throws IllegalArgumentException {
2         Object val = getConfiguration().getImpl(name);
3         return val;
4     }
5
6     public static Configuration getConfiguration() {
7         return configurationImpl == null ? getDefaultConfiguration() : configurationImpl;
8     }

  • Configuration 中定义的两个静态变量defaultImpl 和configurationImpl,还有 一个setConfiguration方法用来设置configurationImpl;
  • defaultImpl 是 WebWork 的默认实现类实例的引用,在每一次读取配置文件时,都会去判断是否在 webwork.properties 是否配置了 webwork.configuration 参数(其实框架是无法实现热读配置文件的,下面会说到,每次判断只是确定读取配置信息,使用的框架默认类还是用户自定义类);
  • 如果设置了在调用 getDefaultConfiguration() 获得自定义读取类引用 configurationImpl,否则返回 WebWork 自己的 Configuration 实现。

       (这里要说一下,随意变动上线系统的配置文件,你会悲剧的,修改前记得问清楚)

 1     private static Configuration getDefaultConfiguration() {
 2         if (defaultImpl == null) {
 3             defaultImpl = new DefaultConfiguration();
 4             try {
 5                 String className = getString("webwork.configuration");
 6                 if (!className.equals(defaultImpl.getClass().getName())) {
 7                     try {
 8                         defaultImpl = (Configuration) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className));
 9                     } catch (Exception e) {
10                         log.error("Could not instantiate configuration", e);
11                     }
12                 }
13                 return defaultImpl;
14             } catch (IllegalArgumentException localIllegalArgumentException) {
15             }
16         }
17         return defaultImpl;
18     }

  • 第一次调用 getDefaultConfiguration() 方法时,默认实现 defaultImpl 是空,则进入创建一 个 WebWork 自己的实现 DefaultConfiguration 的实例,并通过这个实例读取 WebWork 配置信息。
  • 上面代码第5行有个特殊的地方,和下面的 DelegatingConfiguration中的很相似,下面一起说。

回到顶部

2. DefaultConfiguration

 1 public DefaultConfiguration() {
 2         ArrayList list = new ArrayList();
 3         try {
 4             list.add(new PropertiesConfiguration("webwork"));
 5         } catch (Exception e) {
 6             this.log.warn("Could not find webwork.properties");
 7         }
 8         try {
 9             list.add(new PropertiesConfiguration("com/opensymphony/webwork/default"));
10         } catch (Exception e) {
11             this.log.error("Could not find com/opensymphony/webwork/default.properties", e);
12         }
13         Configuration[] configList = new Configuration[list.size()];
14         this.config = new DelegatingConfiguration((Configuration[]) list.toArray(configList));
15         try {
16             StringTokenizer configFiles = new StringTokenizer((String) this.config.getImpl("webwork.custom.properties"), ",");
17             while (configFiles.hasMoreTokens()) {
18                 String name = configFiles.nextToken();
19                 try {
20                     list.add(new PropertiesConfiguration(name));
21                 } catch (Exception e) {
22                     this.log.error("Could not find " + name + ".properties. Skipping");
23                 }
24             }
25             configList = new Configuration[list.size()];
26             this.config = new DelegatingConfiguration((Configuration[]) list.toArray(configList));
27         } catch (IllegalArgumentException localIllegalArgumentException) {
28         }
29         try {
30             StringTokenizer bundleFiles = new StringTokenizer((String) this.config.getImpl("webwork.custom.i18n.resources"), ",");
31             while (bundleFiles.hasMoreTokens()) {
32                 String name = bundleFiles.nextToken();
33                 try {
34                     this.log.info("Loading global messages from " + name);
35                     LocalizedTextUtil.addDefaultResourceBundle(name);
36                 } catch (Exception e) {
37                     this.log.error("Could not find " + name + ".properties. Skipping");
38                 }
39             }
40         } catch (IllegalArgumentException localIllegalArgumentException1) {
41         }
42     }

 

  • DefaultConfiguration 并没有直接取读取properties文件,而是通过 PropertiesConfiguration 来实现properties文件的读取;
  • PropertiesConfiguration 也同样是 Configuration 的子类,通过java.util.Properties 来解析properties文件,并 赋予自身Properties 实例settings,并覆盖了父类的setImpl、getImpl、isSetImpl、 listImpl 四个方法;
  • DefaultConfiguration 通 过 PropertiesConfiguration 首 先 加 载 的 是 webwork.properties,之后又加载了default.properties;

   (这里需要说一下,default.properties 是webwork 框架自身的配置文件,封装在 jar 中,假如你在项目的 web.properties 中定义了与 default.properties 相同的参数,看上面程序配置文件的加载顺序,框架先加载你的配置文件,然后加载默认配置文件,你会发现你的参数是不会起作用的,如果你想让你的参数覆盖框架中的,这里你需要自定义配置文件,并且在 项目 webwork.properties 中配置webwork.custom.properties 参数)

  • 将 PropertiesConfiguration 实例放入List中,然后创建一个和 List一样大的Configuration[]数组,并把List 转型为 Configuration[]赋予 实例化 DelegatingConfiguration
  • 加载完两个properties 文件,并创建了DelegatingConfiguration 实例之后, DefaultConfiguration开始在这两个属性文件中查找 webwork.custom.properties,文件名之间用“,”隔开。找到配置后,分割文件名并分别创建PropertiesConfiguration 实例,加入List,加载完所有配置文 件后重新创建DelegatingConfiguration 实例。
  • 加载完所有的WebWork 属性文件后, 查找属性文件中指定的国际化资源文件(文件名同样用“,”隔开),如果有,则加载到 LocalizedTextUtil 中,供以后使用。

       (毕竟是好多年前编写的源码,这里面的 StringTokenizer 出于兼容性的原因已经被遗留(虽然在新代码中并不鼓励使用它)。API 中建议所有寻求此功能的人使用 String 的 split 方法或 java.util.regex 包)

回到顶部

3. DelegatingConfiguration

  • DelegatingConfiguration 也同样是 Configuration 的子类,内部保存了一个 Configuration[]数组configList,并覆 盖了父类的setImpl、getImpl、isSetImpl、listImpl 四个方法,实现对configList 的操作;
  • 如果用户没有指定自己的 Configuration 实现,则 Configuration.getString 最终调用的是 DelegatingConfiguration 的 getImpl;
  • 在 DelegatingConfiguration 的setImpl 方法实现中,有一个特别的地方,其实也就是上面 Configuration提到的f,底层的实现:

 1     public void setImpl(String name, Object value) throws IllegalArgumentException, UnsupportedOperationException {
 2         IllegalArgumentException e = null;
 3         for (int i = 0; i < this.configList.length; i++) {
 4             try {
 5                 this.configList[i].getImpl(name);
 6
 7                 this.configList[i].setImpl(name, value);
 8
 9                 return;
10             } catch (IllegalArgumentException ex) {
11                 e = ex;
12             }
13         }
14         throw e;
15     }

   WebWork不支持动态的增加属性配置,但允许修改已配置的属性, configList[i].getImpl(name); 调用的是 PropertiesConfiguration 的 getImpl 方法,实现如下:

1     public Object getImpl(String aName) throws IllegalArgumentException {
2         Object setting = this.settings.get(aName);
3         if (setting == null) {
4             throw new IllegalArgumentException("No such setting:" + aName);
5         }
6         return setting;
7     }

    PropertiesConfiguration 会在settings 里去找name,如果找到就返回配置信息,在 DelegatingConfiguration 的setImpl 方法中通过configList[i].setImpl(name, value)修改该属性的配置,否则抛IllegalArgumentException 异常,该异常在 DelegatingConfiguration 的 getImpl 方法中截 获 ,继续往被调用函数抛。 此时则不会执行 configList[i].setImpl(name, value);从而保证了只有配置过了的属性可以被修改,在服务运行的过程中不会有新增的属性,所有的属性都由 Web 服务第一次启动的时候加载。

回到顶部

4. webwork[三][四]小结

    以上分析我们可以看见,Web 服务启动的时候,ServletDispatcher 通过 DefaultConfiguration 先 加 载 webwork.properties 和 default.properties , 并 查 找 webwork.properties中webwork.custom.properties 配置的其他属性文件加载。加载完毕 后再通过属性中配置的 webwork.custom.i18n.resources 加载国际化资源文件供以后 使用。之后再查找 webwork.configuration 属性看是否用户指定了自己的 Configuration 实现,如果有就用用户自己的Configuration 实现,否则返回WebWork 自己的实现(DelegatingConfiguration)。大部分情况下,使用 WebWork 自己的实现 已经足够,用户不需要自己去实现一个 Configuration,除非你想加载XML等格式的配 置文件。

作者:Orson 
出处:http://www.cnblogs.com/java-class/ 
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】 
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】 
如果,您对我的博客内容感兴趣,请继续关注我的后续博客,我是【Orson】 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段 声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 

转载:http://www.cnblogs.com/java-class/p/5113897.html

时间: 2024-08-09 10:50:03

Webwork 学习之路(四)Configuration 详解的相关文章

Webwork 学习之路(三)核心类 ServletDispatcher 的初始化

阅读目录 1. Webwork 与 Xwork 2.Webwork配置 3.核心类 ServletDispatcher 和 它的初始化 回到顶部 1. Webwork 与 Xwork      搭建环境需要的的jar 为:webwork-core-1.0.jar,xwork-1.0.jar,搭建webwork 需要xwork 的jar呢?原因是这样的,WebWork2 被构建在XWork之上,以XWork为基础.通过使用XWork的命令模式框架和拦截器框架,提供了一个支持Web功能.能快速构建W

Asp.Net MVC3 简单入门第一季(四)详解Request Processing Pipeline

引子       很久没更新了,今天写点关于Asp.Net MVC的PipeLine.首先我们确认一点,Asp.Net WebFrom和Asp.Net MVC是在.Net平台下的两种web开发方式.其实他们都是基于Asp.Net Core的不同表现而已.看下面一张图,我们就能理解了WebForm和Asp.Net MVC的一个关系了. 那好我们了解了Asp.Net平台下的两种开发方式,相信大家对于WebForm的Pipeline都非常熟悉了,当然这也是你熟悉Asp.Net开发的必经之路.而看了很多

Webwork 学习之路(六)Action 调用

阅读目录 1.这部分框架类关系 2.Webwork 获取和包装 web 参数 3.DefaultActionProxyFactory.DefaultActionProxy.DefaultActionInvocation       一路走来,终于要开始 webwork 核心业务类的总结,webwork 通过对客户端传递的 web 参数重新包装,进行执行业务 Action 类,并反馈执行结果,本篇源码分析对应下图 WebWork 框架流转图中红色框的地方. 回到顶部 1.这部分框架类关系 回到顶部

kotlin 官方学习教程之基础语法详解

kotlin 官方学习教程之基础语法详解 Google 在今天的举行了 I/O 大会,大会主要主要展示内有容 Android O(Android 8.0)系统.Google Assistant 语音助手.Google 智能音箱.人工智能.机器学习.虚拟现实等.作为一个 Android 开发者,我关心的当然是 Android O(Android 8.0)系统了,那么关于 Android O 系统的一个重要消息是全面支持 Kotlin 编程语言,使得 Kotlin 成为了 Android 开发的官方

JSP学习之------&amp;gt;HTTP协议详解

Author :Jeffrey  My Blog:http://blog.csdn.net/gueter/  引言                                        HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of

Groupon路演幻灯片详解:市值虚高 未来存变数

  北京时间10月25消息,据国外媒体报道,Groupon已开始IPO路演,公司高管逐一讲解了Groupon当前的发展状况和业务内容.路透社的博客撰写人费力克斯-萨蒙(Felix Salmon)对该公司的此次路演进行了详解,并指出Groupon拥有实实在在的业务,绝非某些人所说的庞氏骗局. Groupon IPO路演归纳总结 以下为原文内容摘要: Groupon IPO在互联网上进行的高调路演之举实属罕见.IPO路演内容都略显乏味,一般都是在灰色背景下,倍受领带束缚的公司执行高管们滔滔不绝地讲解

CDN学习笔记二(技术详解)

一本好的入门书是带你进入陌生领域的明灯,<CDN技术详解>绝对是带你进入CDN行业的那盏最亮的明灯.因此,虽然只是纯粹的重点抄录,我也要把<CDN技术详解>的精华放上网.公诸同好. 第一章    引言    "第一公里"是指万维网流量向用户传送的第一个出口,是网站服务器接入互联网的链路所能提供的带宽.这个带宽决定了一个 网站能为用户提供的访问速度和并发访问量.如果业务繁忙,用户的访问数越多,拥塞越严重,网站会在最需要向用户提供服务时失去用户.(还有"中

四步详解站长如何更有效的稳定网站排名

对于网站排名的不能够稳定下来的情况,许多站长都遇到过.而这也是让站长非常苦恼的事,因为自己好不容易把网站排名优化上来了,可能是因为搜索引挚算法改变的原因,以致于自己的网站还没坐稳当前的排名位置就出现了下降的情况了.对于这个情况,笔者认为最主要的原因还是出现在网站身上,毕竟搜索引挚的算法再怎么改变都是围绕着一个核心的,如果你的网站能得到其核心的认可,自然稳定排名就不是问题了.今天笔者详解站长如何更有效的稳定网站排名: 合理的优化网站结构 网站的结构是否合理,对于网站排名能否稳定非常重要.而且拥有利

Spring学习(三) AOP详解

上次的博文深入浅出Spring(二) IoC详解中,我为大家简单介绍了一下Spring框架核心内容中的IoC,接下来我们继续讲解另一个核心AOP(Aspect Oriented Programming),即面向切面编程. 1.OOP回顾 在介绍AOP之前先来回顾一下大家都比较熟悉的OOP(Object Oriented Programming).OOP主要是为了实现编程的重用性.灵活性和扩展性.它的几个特征分别是继承.封装.多态和抽象.OOP重点体现在编程架构,强调的是类之间的层次关系. 2.O