Struts2源码阅读(四)_Dispatcher&ConfigurationProvider续 .

807人阅读 评论(0) 收藏 举报

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

  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.   }  

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

  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. }    

第六步:init_FilterInitParameters

  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.     }   

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

  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.  }    

展开DefaultConfiguration中的reloadContainer

  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.   }     

Come From :http://qidaoxp.javaeye.com/blog/497052

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值