Struts2源码学习-DefaultConfiguration的RuntimeConfigurationImpl方法(运行期改造)
2013-02-03 08:22
381 查看
DefaultConfiguration的RuntimeConfigurationImpl方法是对所有的packageConfig进行namespace的重新分类,这样做的目的在于当Xwork框架响应Http请求时,可以根据namepace进行URL匹配。
下面介绍这个方法的,它也用到了递归方法
这个方法主要是将程序配置中的数据结构创建成一个内部的运行中的配置文件,Xwork可以在其中查找一个action,他将数据结构扁平化处理,使数据更加容易的访问,他接受一个ActionConfig,将它的包和包的父包(EXTENDS关键字指定的包)的公共对象找到,例如:如果一个action包含了一个result,但是所在的包包含一个全局的result对象,那么这个action就将包含连个result对象。
packageConfig.getAllActionConfigs()方法:注意递归方法的使用
找到包对应的action-ref值的,一个包只能定义一个默认调用的action,当当前的action找不到的时候,那么调用他的父亲的父亲,一直向上遍历,直至找到为止,如果自动没知道,则返回null,这里也使用了递归的方法
下面介绍这个方法的,它也用到了递归方法
这个方法主要是将程序配置中的数据结构创建成一个内部的运行中的配置文件,Xwork可以在其中查找一个action,他将数据结构扁平化处理,使数据更加容易的访问,他接受一个ActionConfig,将它的包和包的父包(EXTENDS关键字指定的包)的公共对象找到,例如:如果一个action包含了一个result,但是所在的包包含一个全局的result对象,那么这个action就将包含连个result对象。
/** * This builds the internal runtime configuration used by Xwork for finding and configuring Actions from the * programmatic configuration data structures. All of the old runtime configuration will be discarded and rebuilt. * * <p> * It basically flattens the data structures to make the information easier to access. It will take * an {@link ActionConfig} and combine its data with all inherited dast. For example, if the {@link ActionConfig} * is in a package that contains a global result and it also contains a result, the resulting {@link ActionConfig} * will have two results. */ protected synchronized RuntimeConfiguration buildRuntimeConfiguration() throws ConfigurationException { 命名空间和这个命名空间包含的所有的package包含的所有的action配置 Map<String, Map<String, ActionConfig>> namespaceActionConfigs = new LinkedHashMap<String, Map<String, ActionConfig>>(); 命名空间和这个命名空间的所有的包的默认的action:即通过 <default-action-ref>属性配置的 Map<String, String> namespaceConfigs = new LinkedHashMap<String, String>(); for (PackageConfig packageConfig : packageContexts.values()) { 如果当前的包属于抽象类型(不需要在包内定义action) if (!packageConfig.isAbstract()) { 包对应的命名空间 String namespace = packageConfig.getNamespace(); 查询出该命名空间对应的anction配置,其中这个map:configs String对应的是action的名字,actionConfig对应的这个action的各种配置信息 19 Map<String, ActionConfig> configs = namespaceActionConfigs.get(namespace); 20 如果为空,证明刚刚开始初始化,这个命名空间对应的action的map信息,则重新生成一个 如果不为空,证明之前已经生成了该命名空间对应的action的map信息, 举例说明:一个配置文件中,有两个包,包A和包B的命名空间一致,上面的循环,先加载A,则 configs为空,但加载B的时候,针对该命名空间已经从在了configs,则不为空,包A和包B中的 action都加载到了这个map中 if (configs == null) { configs = new LinkedHashMap<String, ActionConfig>(); } 这个packageConfig.getAllActionConfigs()方法又用到了一个很经典的递归算法,下面对其进行分析 25 Map<String, ActionConfig> actionConfigs = packageConfig.getAllActionConfigs(); 26 这个actionConfig包含了针对该包和包的父亲(祖先,父亲的父亲的父亲等等)的所有的action的配置, for (Object o : actionConfigs.keySet()) { String actionName = (String) o; ActionConfig baseConfig = actionConfigs.get(actionName); configs.put(actionName, buildFullActionConfig(packageConfig, baseConfig)); } 将该命名空间对应的所有存储action配置信息的map放到map映射中, 35 namespaceActionConfigs.put(namespace, configs); 下面的方式是获取命名空间中 if (packageConfig.getFullDefaultActionRef() != null) { namespaceConfigs.put(namespace, packageConfig.getFullDefaultActionRef()); } } } return new RuntimeConfigurationImpl(namespaceActionConfigs, namespaceConfigs); }
packageConfig.getAllActionConfigs()方法:注意递归方法的使用
/** * returns the Map of all the ActionConfigs available in the current package. * ActionConfigs defined in ancestor packages will be included in this Map. * * @return a Map of ActionConfig Objects with the action name as the key * @see ActionConfig */ public Map<String, ActionConfig> getAllActionConfigs() { Map<String, ActionConfig> retMap = new LinkedHashMap<String, ActionConfig>(); 判断有没有父亲。即是否存在extend属性 --找到所有的祖先的的actionConfig信息 if (!parents.isEmpty()) { for (PackageConfig parent : parents) { 递归调用出现了。 retMap.putAll(parent.getAllActionConfigs()); } } --加入当前的包对应的actionConfig信息 retMap.putAll(getActionConfigs()); return retMap; }
找到包对应的action-ref值的,一个包只能定义一个默认调用的action,当当前的action找不到的时候,那么调用他的父亲的父亲,一直向上遍历,直至找到为止,如果自动没知道,则返回null,这里也使用了递归的方法
/** * gets the default action-ref name. If this is not set on this PackageConfig, it searches the parent * PackageConfigs in order until it finds one. */ public String getFullDefaultActionRef() { if ((defaultActionRef == null) && !parents.isEmpty()) { for (PackageConfig parent : parents) { --递归调用。 String parentDefault = parent.getFullDefaultActionRef(); if (parentDefault != null) { return parentDefault; } } } return defaultActionRef; }
相关文章推荐
- Struts源码学习-XmlConfigurationProvider的loadPackages()方法递归调用
- jQuery源码学习之五 (jQUery继承方法)
- jQuery源码学习之三 (jQUery对象的实例属性和方法)
- 从Monkey源码里学习几个adb shell命令和monekey日志的查阅方法
- 码农小汪-struts2学习5-表单的验证的两种方法
- Struts2中的Unable to load configuration错误的分析与解决方法
- jQuery源码学习3——工具方法篇
- Struts2源码学习(一)准备工作
- struts2源码学习之初始化(二)
- Spring源码学习之: 通过Spring @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
- springMvc源码学习之:spirngMVC获取请求参数的方法2
- jQuery源码研究分析学习笔记-静态方法和属性(10)
- struts2学习笔记--获取Session和request方法
- Collection源码学习之toArray方法
- struts2学习笔记---获得HttpServletResponse或HttpServletRequest对象的几种方法
- iOS runtime学习之Method Swizzling(方法调配技术)
- ios开发runtime学习三:动态添加方法(实际应用少,面试)
- Struts2.x学习四(在Action中定义多个方法)
- jQuery源码学习之五 (jQUery继承方法)
- HADOOP源码学习思路与方法