Struts2源码阅读(四)_DispatcherConfigurationProvider续
生活随笔
收集整理的這篇文章主要介紹了
Struts2源码阅读(四)_DispatcherConfigurationProvider续
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
接下來第三步:init_LegacyStrutsProperties()
調用的是調用的是LegacyPropertiesConfigurationProvider
通過比較前面DefaultPropertiesProvider與調用的是LegacyPropertiesConfigurationProvider.
發現DefaultPropertiesProvider繼承自后者,但重寫了register()方法,主要是生成PropertiesSetting的不同,前者是根據org/apache/struts2/default.properties
后者是根據struts.properties
這是將配置文件中定義的<bean>與實際的類相映射,就是注入bean的依賴關系,這部分以后有時候再研究Container
?
接下來是看怎樣調用這些ConfigurationProviders
展開init_PreloadConfiguration()
調用的是調用的是LegacyPropertiesConfigurationProvider
通過比較前面DefaultPropertiesProvider與調用的是LegacyPropertiesConfigurationProvider.
發現DefaultPropertiesProvider繼承自后者,但重寫了register()方法,主要是生成PropertiesSetting的不同,前者是根據org/apache/struts2/default.properties
后者是根據struts.properties
我們展開register()中的Settings.getInstance(),最后是調用getDefaultInstance()
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
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
//從這里可以看出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()
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
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; }
總結
以上是生活随笔為你收集整理的Struts2源码阅读(四)_DispatcherConfigurationProvider续的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将文件内含有的特殊字符还原
- 下一篇: Java并发编程实战~软件事务内存