首页 > Web开发 > 详细

Webwork 学习之路(五)请求跳转前 xwork.xml 的读取

时间:2016-01-14 12:05:12      阅读:199      评论:0      收藏:0      [点我收藏+]

      个人理解 WebWork 与 Struts2 都是将xml配置文件作为 Controler 跳转的基本依据,WebWork 跳转 Action 前 xml 文件的读取依赖 xwork-1.0.jar,底层由 xwork实现,这部门代码读起来不是很轻松,在此做下记录供后续查阅和项目借鉴。这几段代码对应 下图 WebWork 框架流转图中红框框的地方。

技术分享

      WebWork xml配置文件读取的入口、后续的所有处理都是 Action 调用类 DefaultActionProxy 这句代码:

 this.config = ConfigurationManager.getConfiguration().getRuntimeConfiguration().getActionConfig(namespace, actionName);

1. 框架中类图关系

技术分享

2. ConfigurationManager

  •  ConfigurationManager 做为整个 xwork 获取配置信息的管理者,掌控 Configuration 与 XmlConfigurationProvider 两大类的实例化时机;
  •  ConfigurationManager的 getConfiguration()方法实现如下:
1     public static synchronized Configuration getConfiguration() {
2         if (configurationInstance == null) {
3             configurationInstance = new DefaultConfiguration();
4             configurationInstance.reload();
5         } else {
6             conditionalReload();
7         }
8         return configurationInstance;
9     }
  •  注意框架中的这个方法前面的修饰符是 synchronized 并发线程不能同时访问该函数;
  •  可以通过 setConfiguration方法设置一个 configurationInstance,如果没有设置,返回XWork的默认实现类, DefaultConfiguration;

3. DefaultConfiguration

  •  DefaultConfiguration 实现接口 Configuration ,其中含有内部类 RuntimeConfigurationImpl 实现了 RuntimeConfiguration 接口;
  •  入口中DefaultActionProxy的构造函数中调用的:ConfigurationManager.getConfiguration().getRuntimeConfiguration().getActionConfig 默认的实现为 RuntimeConfigurationImpl ;
  •  ConfigurationManager 在实例化 DefaultConfiguration 对象后,紧接着调用了该对象的 reload();
1     public synchronized void reload() throws ConfigurationException {
2         this.packageContexts.clear();
3         for (Iterator iterator = ConfigurationManager.getConfigurationProviders().iterator(); iterator.hasNext();) {
4             ConfigurationProvider provider = (ConfigurationProvider) iterator.next();
5             provider.init(this);
6         }
7         rebuildRuntimeConfiguration();
8     }
  • reload() 通过遍历 ConfigurationManager 中的configurationProviders链表,来逐个初始化 XWork 的配置信息。默认只有一个 ConfigurationProvider,也就是 XmlConfigurationProvider,同样只会读取一个XWork的配置信息,就是xwork.xml;
  • 这里要注意一下,大项目都是许多工程师并发编写,一个xwork.xml 配置文件显示是不能满足各个模块一起开发的要求,这里需要编写一个类去继承 XmlConfigurationProvider,这个类需要将项目中分散在各个模块下的 xwork.xml 配置文件整合起来,写入到加载到 configurationProviders 链表当中(实现方式多种多样,看项目具体情况);

ConfigurationManager的 getConfigurationProviders方法实现如下:

    public static List getConfigurationProviders() {
        synchronized (configurationProviders) {
            if (configurationProviders.size() == 0) {
                configurationProviders.add(new XmlConfigurationProvider());
            }
            return configurationProviders;
        }
    }
  • 在没继承 XmlConfigurationProvider 情况下,reload 函数里的 For 循环只会执行一次,调用XmlConfigurationProvider的 init方法;
  • 调用该方法时, DefaultConfiguration把自身作为参数传了进去。 之后 XmlConfigurationProvider 的 init 方法会通过自身的loadConfigurationFile方法回调DefaultConfiguration的addPackageConfig方法将解析出的 Action 配置信息存放回 DefaultConfiguration 的Map 类型成员变量 packageContexts 中,供其内部类 RuntimeConfigurationImpl 的方法getActionConfig 返回某一个 Action 配置信息时查找使用;
  • getActionConfig 返回的 ActionConfig 是 XWork 的一个类,包含了某一个 Action 的所有配置信息以及执行后的所有可能结果等;
  • XmlConfigurationProvider 的 init 方法会通过自身的 loadConfigurationFile 方法首先读取xwork.xml配置信息,然后通过发现include标签找到其他配置文件去读取;
  • 该机制保证了用户可以将一个庞大的XWork配置文件拆分为多个,在 xwork.xml通过 include标签引用进来,但要注意同名的 Action的覆盖问题[和上面说的注意区别]。
  • loadConfigurationFile 通过递归解析完所有的配置文件,并将他们放入DefaultConfiguration的Map类型成员变量packageContexts中。   

具体代码如下:

 1 private void loadConfigurationFile(String fileName, DocumentBuilder db) {
 2         if (!includedFileNames.contains(fileName)) {
 3             if (LOG.isDebugEnabled()) {
 4                 LOG.debug("Loading xwork configuration from: " + fileName);
 5             }
 6             includedFileNames.add(fileName);
 7             Document doc = null;
 8             InputStream is = null;
 9             try {
10                 is = getInputStream(fileName);
11                 if (is == null) {
12                     throw new Exception("Could not open file " + fileName);
13                 }
14                 doc = db.parse(is);
15             } catch (Exception e) {
16                 final String s = "Caught exception while loading file " + fileName;
17                 LOG.error(s, e);
18                 throw new ConfigurationException(s, e);
19             } finally {
20                 if (is != null) {
21                     try {
22                         is.close();
23                     } catch (IOException e) {
24                         LOG.error("Unable to close input stream", e);
25                     }
26                 }
27             }
28             Element rootElement = doc.getDocumentElement();
29             NodeList children = rootElement.getChildNodes();
30             int childSize = children.getLength();
31             for (int i = 0; i < childSize; i++) {
32                 Node childNode = children.item(i);
33                 if (childNode instanceof Element) {
34                     Element child = (Element) childNode;
35                     final String nodeName = child.getNodeName();
36                     if (nodeName.equals("package")) {
37                         addPackage(child);
38                     } else if (nodeName.equals("include")) {
39                         String includeFileName = child.getAttribute("file");
40                         loadConfigurationFile(includeFileName, db);
41                     }
42                 }
43             }
44             if (LOG.isDebugEnabled()) {
45                 LOG.debug("Loaded xwork configuration from: " + fileName);
46             }
47         }
48     }

Webwork 学习之路(五)请求跳转前 xwork.xml 的读取

原文:http://www.cnblogs.com/java-class/p/5125183.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!