2013-01-28 22:04:52.0|分类: struts源码分析|浏览量: 1482
前面分析了Dispatcher的init()方法中加载了各种配置文件配置器,并且根据配置文件创建了相应的ConfigurationProvider,各个ConfigurationProvider中的init(),register()方法在哪调用的呢? 首先介绍一下configuration和ConfigurationManager元素:
配置管理元素(configuration)作用: (1)提供框架级对所有配置元素的访问操作接口 (2)对所有的配置元素进行初始化调度 ConfigurationManager是整个配置元素进行操作的代理接口类,而真正对所有配置元素的初始化进行调度的是Configuration对象. 配置元素的加载器:容器加载器(ContainerProvider)和事件映射加载器(PackageProvider)封装与ConfigurationManager内部,对真正的配置元素与配置元素加载器进行严格的分离,使得Configuration和configurationManager对象的职责划分更为清晰。 这里贴出一张分析到加载action标签流程图: 下面就慢慢来看吧,Dispatcher中init()方法中部分代码:
Container container = init_PreloadConfiguration(); container.inject(this);1、init_PreloadConfiguration() 代码:
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; } 注释: configurationManager对象将初始化过程与元素调度过程和而为一的对象,主要目的是为了简化上层对象对配置调度的过程。不仅获得了Configuration对象,同时完成了对所有配置元素的调度。 通过配置管理器获得Configuration,具体怎么获得,请继续看 2、getConfiguration()代码:
/** * Get the current XWork configuration object. By default an instance of DefaultConfiguration will be returned * * @see com.opensymphony.xwork2.config.impl.DefaultConfiguration */ public synchronized Configuration getConfiguration() { if (configuration == null) { setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName)); try { configuration.reloadContainer(getContainerProviders()); } catch (ConfigurationException e) { setConfiguration(null); throw new ConfigurationException("Unable to load configuration.", e); } } else { conditionalReload(); } return configuration; }注释:configuration是com.opensymphony.xwork2.config.impl.DefaultConfiguration类型,如果 configuration为空,new DefaultConfiguration 新对象。 3、onfiguration.reloadContainer(getContainerProviders())代码: 首先解释一下reloadContainer传参ContainerProvider,而前面我们添加继承ConfigurationProvider,这2个类不一样啊?笔者看到这里,也疑惑了,没办法研究研究,看看类与类直接有什么联系? public interface ConfigurationProvider extends ContainerProvider, PackageProvider {
public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException { //内部缓存对象的清理工作 packageContexts.clear(); loadedFileNames.clear(); List<PackageProvider> packageProviders = new ArrayList<PackageProvider>(); //初始化所有Properties文件中相关运行参数的主要操作对象 ContainerProperties props = new ContainerProperties(); ContainerBuilder builder = new ContainerBuilder(); for (final ContainerProvider containerProvider : providers) { containerProvider.init(this); containerProvider.register(builder, props);//循环调用ConfigurationProvider的init和register方法,明白了吧,在这里统一循环调用 } 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)containerProvider).loadPackages();//调用PackageProvider的loadPackages()方法,这里主要是针对XmlConfigurationProvider和StrutsXmlConfigurationProvider 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); } } 对所有的packageConfig进行namespace级别的重新分类,这样做的目的在于当xwork框架相应http请求时可以根据namespace进行url匹配 rebuildRuntimeConfiguration(); } finally { if (oldContext == null) { ActionContext.setContext(null); } } return packageProviders; }注释:上面代码中 containerProvider.init(this); containerProvider.register(builder, props); loadPackages()方法我们在上一篇文章分析了,这就不再赘述。
|