`
mujun1209
  • 浏览: 20750 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Struts2--Dispatcher&ConfigurationProvider续

阅读更多

接下来第三步:init_LegacyStrutsProperties()
调用的是调用的是LegacyPropertiesConfigurationProvider
通过比较前面DefaultPropertiesProvider与调用的是LegacyPropertiesConfigurationProvider.
发现DefaultPropertiesProvider继承自后者,但重写了register()方法,主要是生成PropertiesSetting的不同,前者是根据org/apache/struts2/default.properties
后者是根据struts.properties
我们展开register()中的Settings.getInstance(),最后是调用getDefaultInstance()

Java代码 复制代码
  1.  private static Settings getDefaultInstance() {   
  2.      if (defaultImpl == null) {   
  3.          // Create bootstrap implementation   
  4. //不带参数的DefaultSettings(),区别与DefaultPropertiesProvider中直接带default.properties参数   
  5. //不带参数就是默认为struts.propertes,并且加载struts.custom.properties所定义的properties文件   
  6.          defaultImpl = new DefaultSettings();   
  7.   
  8.          // Create default implementation   
  9.          try {   
  10.     //STRUTS_CONFIGURATION为:struts.configuration   
  11.     //在struts.proterties中查找struts.configuration的值,这个值必须是org.apache.struts2.config.Configuration接口的实现类   
  12.     //所以我有个困惑就是在下面的转换当中怎么将Configuration转换成Setting类型的...   
  13.     //这一点先放下了,有时间再研究   
  14.              String className = get(StrutsConstants.STRUTS_CONFIGURATION);   
  15.   
  16.              if (!className.equals(defaultImpl.getClass().getName())) {   
  17.                  try {   
  18.                      // singleton instances shouldn't be built accessing request or session-specific context data   
  19.                      defaultImpl = (Settings) ObjectFactory.getObjectFactory().buildBean(Thread.currentThread().getContextClassLoader().loadClass(className), null);   
  20.                  } catch (Exception e) {   
  21.                      LOG.error("Settings: Could not instantiate the struts.configuration object, substituting the default implementation.", e);   
  22.                  }   
  23.              }   
  24.          } catch (IllegalArgumentException ex) {   
  25.              // ignore   
  26.           
    private static Settings getDefaultInstance() {
        if (defaultImpl == null) {
            // Create bootstrap implementation
			//不带参数的DefaultSettings(),区别与DefaultPropertiesProvider中直接带default.properties参数
			//不带参数就是默认为struts.propertes,并且加载struts.custom.properties所定义的properties文件
            defaultImpl = new DefaultSettings();

            // Create default implementation
            try {
			    //STRUTS_CONFIGURATION为:struts.configuration
				//在struts.proterties中查找struts.configuration的值,这个值必须是org.apache.struts2.config.Configuration接口的实现类
				//所以我有个困惑就是在下面的转换当中怎么将Configuration转换成Setting类型的...
				//这一点先放下了,有时间再研究
                String className = get(StrutsConstants.STRUTS_CONFIGURATION);

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

 

在2.1.6中去掉了第四步:init_ZeroConfiguration();
第五步是自定义的configProviders

Java代码 复制代码
  1. private void init_CustomConfigurationProviders() {   
  2.     //从这里可以看到可以将自定义的Provider定义在web.xml中FilterDispatcher的param中:configProviders   
  3.     String configProvs = initParams.get("configProviders");   
  4.     if (configProvs != null) {   
  5.         String[] classes = configProvs.split("\\s*[,]\\s*");   
  6.         for (String cname : classes) {   
  7.             try {   
  8.                 Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());   
  9.                 ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance();   
  10.                 configurationManager.addConfigurationProvider(prov);   
  11.             }    
  12. ...   
  13.         }   
  14.     }   
  15. }  
    private void init_CustomConfigurationProviders() {
        //从这里可以看到可以将自定义的Provider定义在web.xml中FilterDispatcher的param中:configProviders
        String configProvs = initParams.get("configProviders");
        if (configProvs != null) {
            String[] classes = configProvs.split("\\s*[,]\\s*");
            for (String cname : classes) {
                try {
                    Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
                    ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance();
                    configurationManager.addConfigurationProvider(prov);
                } 
				...
            }
        }
    }

 

第六步:init_FilterInitParameters

Java代码 复制代码
  1. //从这里可以看出struts.properties中的属性不仅可以在struts.xml中以constant形式定义,而且可以在FilterDispatcher的param中定义     
  2.     private void init_FilterInitParameters() {   
  3.         configurationManager.addConfigurationProvider(new ConfigurationProvider() {   
  4.             public void destroy() {}   
  5.             public void init(Configuration configuration) throws ConfigurationException {}   
  6.             public void loadPackages() throws ConfigurationException {}   
  7.             public boolean needsReload() { return false; }   
  8.   
  9.             public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {   
  10.                 props.putAll(initParams);//在这里实现滴~   
  11.             }   
  12.         });   
  13.     }     
//从这里可以看出struts.properties中的属性不仅可以在struts.xml中以constant形式定义,而且可以在FilterDispatcher的param中定义	
    private void init_FilterInitParameters() {
        configurationManager.addConfigurationProvider(new ConfigurationProvider() {
            public void destroy() {}
            public void init(Configuration configuration) throws ConfigurationException {}
            public void loadPackages() throws ConfigurationException {}
            public boolean needsReload() { return false; }

            public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
                props.putAll(initParams);//在这里实现滴~
            }
        });
    }	

 

第七步:init_AliasStandardObjects,使用BeanSelectionProvider
这是将配置文件中定义的<bean>与实际的类相映射,就是注入bean的依赖关系,这部分以后有时候再研究Container
 
接下来是看怎样调用这些ConfigurationProviders
展开init_PreloadConfiguration()

Java代码 复制代码
  1.  private Container init_PreloadConfiguration() {   
  2.      Configuration config = configurationManager.getConfiguration();   
  3.      Container container = config.getContainer();   
  4.   
  5.      boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));   
  6.      LocalizedTextUtil.setReloadBundles(reloadi18n);   
  7.   
  8.      return container;   
  9.  }   
  10.       //再看getConfiguration()   
  11.  public synchronized Configuration getConfiguration() {   
  12.      if (configuration == null) {   
  13.          setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));   
  14.          try {   
  15. //重点就是这个reloadContainer   
  16.              configuration.reloadContainer(getContainerProviders());   
  17.          } catch (ConfigurationException e) {   
  18.              setConfiguration(null);   
  19.              throw new ConfigurationException("Unable to load configuration.", e);   
  20.          }   
  21.      } else {   
  22.          conditionalReload();   
  23.      }   
  24.   
  25.      return configuration;   
  26.  }  
    private Container init_PreloadConfiguration() {
        Configuration config = configurationManager.getConfiguration();
        Container container = config.getContainer();

        boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));
        LocalizedTextUtil.setReloadBundles(reloadi18n);

        return container;
    }
         //再看getConfiguration()
    public synchronized Configuration getConfiguration() {
        if (configuration == null) {
            setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
            try {
			//重点就是这个reloadContainer
                configuration.reloadContainer(getContainerProviders());
            } catch (ConfigurationException e) {
                setConfiguration(null);
                throw new ConfigurationException("Unable to load configuration.", e);
            }
        } else {
            conditionalReload();
        }

        return configuration;
    }

 

展开DefaultConfiguration中的reloadContainer

Java代码 复制代码
  1.   public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {   
  2.       packageContexts.clear();   
  3.       loadedFileNames.clear();   
  4.       List<PackageProvider> packageProviders = new ArrayList<PackageProvider>();   
  5.   
  6. //Struts2(xwork2)用Container来完成依赖注入的功能   
  7. //首先初始化一个ContainerBuilder,再由builder来保存接口与实现类或工厂类的对应关系   
  8. //然后通过builder.create(boolean)方法产生container   
  9. //由container.getInstance(Class);就可以得到接口的实现实例了   
  10. //这一部分比较复杂,后面研究完成了,会单独拿出来讲,这里先弄清楚Xwork依赖注入的实现步骤就可以了   
  11.       ContainerProperties props = new ContainerProperties();   
  12.       ContainerBuilder builder = new ContainerBuilder();   
  13.       for (final ContainerProvider containerProvider : providers)   
  14.       {   
  15.     //循环调用ConfigurationProvider的init和register方法,明白了吧,在这里统一循环调用   
  16.           containerProvider.init(this);   
  17.           containerProvider.register(builder, props);   
  18.       }   
  19.       props.setConstants(builder);   
  20.       //注入依赖关系,在这里并不产生实例   
  21.       builder.factory(Configuration.classnew Factory<Configuration>() {   
  22.           public Configuration create(Context context) throws Exception {   
  23.               return DefaultConfiguration.this;   
  24.           }   
  25.       });   
  26.   
  27.       ActionContext oldContext = ActionContext.getContext();   
  28.       try {   
  29.           // Set the bootstrap container for the purposes of factory creation   
  30.           Container bootstrap = createBootstrapContainer();   
  31.           setContext(bootstrap);   
  32.     //create已经注入依赖关系的Container   
  33.           container = builder.create(false);   
  34.           setContext(container);   
  35.           objectFactory = container.getInstance(ObjectFactory.class);   
  36.   
  37.           // Process the configuration providers first   
  38.           for (final ContainerProvider containerProvider : providers)   
  39.           {   
  40.               if (containerProvider instanceof PackageProvider) {   
  41.                   container.inject(containerProvider);   
  42.             //调用PackageProvider的loadPackages()方法,这里主要是针对XmlConfigurationProvider和StrutsXmlConfigurationProvider   
  43.                   ((PackageProvider)containerProvider).loadPackages();   
  44.                   packageProviders.add((PackageProvider)containerProvider);   
  45.               }   
  46.           }   
  47.   
  48.           // Then process any package providers from the plugins   
  49.           Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);   
  50.           if (packageProviderNames != null) {   
  51.               for (String name : packageProviderNames) {   
  52.                   PackageProvider provider = container.getInstance(PackageProvider.class, name);   
  53.                   provider.init(this);   
  54.                   provider.loadPackages();   
  55.                   packageProviders.add(provider);   
  56.               }   
  57.           }   
  58.   
  59.           rebuildRuntimeConfiguration();   
  60.       } finally {   
  61.           if (oldContext == null) {   
  62.               ActionContext.setContext(null);   
  63.           }   
  64.       }   
  65.       return packageProviders;   
  66.   }   
    public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {
        packageContexts.clear();
        loadedFileNames.clear();
        List<PackageProvider> packageProviders = new ArrayList<PackageProvider>();

		//Struts2(xwork2)用Container来完成依赖注入的功能
		//首先初始化一个ContainerBuilder,再由builder来保存接口与实现类或工厂类的对应关系
		//然后通过builder.create(boolean)方法产生container
		//由container.getInstance(Class);就可以得到接口的实现实例了
		//这一部分比较复杂,后面研究完成了,会单独拿出来讲,这里先弄清楚Xwork依赖注入的实现步骤就可以了
        ContainerProperties props = new ContainerProperties();
        ContainerBuilder builder = new ContainerBuilder();
        for (final ContainerProvider containerProvider : providers)
        {
		    //循环调用ConfigurationProvider的init和register方法,明白了吧,在这里统一循环调用
            containerProvider.init(this);
            containerProvider.register(builder, props);
        }
        props.setConstants(builder);
        //注入依赖关系,在这里并不产生实例
        builder.factory(Configuration.class, new Factory<Configuration>() {
            public Configuration create(Context context) throws Exception {
                return DefaultConfiguration.this;
            }
        });

        ActionContext oldContext = ActionContext.getContext();
        try {
            // Set the bootstrap container for the purposes of factory creation
            Container bootstrap = createBootstrapContainer();
            setContext(bootstrap);
			//create已经注入依赖关系的Container
            container = builder.create(false);
            setContext(container);
            objectFactory = container.getInstance(ObjectFactory.class);

            // Process the configuration providers first
            for (final ContainerProvider containerProvider : providers)
            {
                if (containerProvider instanceof PackageProvider) {
                    container.inject(containerProvider);
					//调用PackageProvider的loadPackages()方法,这里主要是针对XmlConfigurationProvider和StrutsXmlConfigurationProvider
                    ((PackageProvider)containerProvider).loadPackages();
                    packageProviders.add((PackageProvider)containerProvider);
                }
            }

            // Then process any package providers from the plugins
            Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);
            if (packageProviderNames != null) {
                for (String name : packageProviderNames) {
                    PackageProvider provider = container.getInstance(PackageProvider.class, name);
                    provider.init(this);
                    provider.loadPackages();
                    packageProviders.add(provider);
                }
            }

            rebuildRuntimeConfiguration();
        } finally {
            if (oldContext == null) {
                ActionContext.setContext(null);
            }
        }
        return packageProviders;
    }	

 

分享到:
评论

相关推荐

    基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip

    基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip基于Android Studio的个人记账应用帮助用户轻松管理和跟踪他们的财务源码.zip

    基于python实现树莓派和传感器的植物生长环境评估信息系统

    【作品名称】:基于python实现树莓派和传感器的植物生长环境评估信息系统 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:基于python实现树莓派和传感器的植物生长环境评估信息系统

    优质资源,Yearning Mysql SQL审核平台

    Yearning Mysql SQL审核平台(使用go语言)

    c语言课程设计-职工资源管理系统.rar

    void displayMenu() { printf("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+ 职工资源管理系统 +\n"); printf("+ +\n"); printf("+ 1. 录入职工信息 +\n"); printf("+ 2. 显示全部职工信息 +\n"); printf("+ 3. 根据工号查询

    华为OD机试D卷 - 来自异国的客人 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    2024华为OD机试D卷 - 最长的指定瑕疵度的元音子串 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    基于nodejs电影交流网站(源码 + 说明文档)

    基于nodejs电影交流网站(源码 + 说明文档) 第二章 开发技术介绍 1 2.2.1 Nodejs技术 1 2.2.2 mysql数据库介绍 1 2.2.3 MySQL环境配置 1 2.2.4 B/S架构 2 2.2.5 Vue框架 2 第三章 系统分析 1 3.1 可行性分析 1 3.1.1 技术可行性 1 3.1.2操作可行性 1 3.1.3 经济可行性 1 3.2性能需求分析 1 3.3功能分析 2 第四章 系统设计 4 4.1功能结构 4 4.2 数据库设计 4 4.2.1 数据库E/R图 4 4.2.2 数据库表 5 第五章 系统功能实现 11 5.1系统功能模块 11 5.2后台登录模块 12 5.2.1管理员功能 13 5.2.2 用户功能 15 第六章 系统测试 16

    setuptools-0.9.8.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    setuptools-23.2.1.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    setuptools-10.0.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    App工具查看md5、公钥等信息

    App工具查看md5、公钥等信息

    2024华为OD机试D卷 - 高效的任务规划 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    基于co-revDSD方法的计算程序

    基于co-revDSD方法的计算程序

    setuptools-54.0.0-py3-none-any.whl

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    课程设计 基于FPGA的电子表源码+全部资料齐全.zip

    【资源说明】 课程设计 基于FPGA的电子表源码+全部资料齐全.zip课程设计 基于FPGA的电子表源码+全部资料齐全.zip 【备注】 1、该项目是高分课程设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过mac/window10/11/linux测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!

    Fig0309.tif

    Fig0309.tif

    setuptools-5.0.zip

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    setuptools-8.0.1.tar.gz

    Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。

    华为OD机试D卷 - 连续字母长度 - 免费看解析和代码.html

    私信博主免费获取真题解析以及代码

    第十章 Python标准库(jupyter版 人工智能编程基础)

    第十章 Python标准库(jupyter版 人工智能编程基础)

Global site tag (gtag.js) - Google Analytics