`
mujun1209
  • 浏览: 20762 次
  • 性别: 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;
    }	

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics