- 浏览: 841888 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
renzhengzhi:
请教一下楼主,公有云和私有云的开发,具体要做哪些工作呢?我拿到 ...
4,云的4 种模式 -
SangBillLee:
我用了solr5.5,用SolrQuery查询,没法高亮,不知 ...
solr5.x快速入门 -
lw900925:
这翻译读起来真是别扭。
solr in action翻译-第一章1.1 -
springjpa_springmvc:
spring mvc demo教程源代码下载,地址:http: ...
Spring MVC性能提升 -
h416373073:
正遇到了此问题不知如何解决, 多谢分享
solr错误
在init初始化方法中我们看到这样一句
InitOperations init = new InitOperations();
这个类没什么作用,就是一个辅助类,来完成初始化的操作。
继续往下看
FilterHostConfig config = new FilterHostConfig(filterConfig); init.initLogging(config); Dispatcher dispatcher = init.initDispatcher(config); init.initStaticContentLoader(config, dispatcher);
创建了FilterHostConfig,这个类也没什么作用就是包装FilterConfig
用官方的原话说
Host configuration that wraps FilterConfig
通过传入一个filterConfig完成该类的初始化。
public class FilterHostConfig implements HostConfig { private FilterConfig config; public FilterHostConfig(FilterConfig config) { this.config = config; } public String getInitParameter(String key) { return config.getInitParameter(key); } public Iterator<String> getInitParameterNames() { return MakeIterator.convert(config.getInitParameterNames()); } public ServletContext getServletContext() { return config.getServletContext(); } }
该类处理完成,真正的初始化才开始,通过初始化辅助类InitOperations来完成初始化。
首先初始化日志信息
init.initLogging(config);
public void initLogging( HostConfig filterConfig ) { String factoryName = filterConfig.getInitParameter("loggerFactory"); if (factoryName != null) { try { Class cls = ClassLoaderUtil.loadClass(factoryName, this.getClass()); LoggerFactory fac = (LoggerFactory) cls.newInstance(); LoggerFactory.setLoggerFactory(fac); } catch ( InstantiationException e ) { System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default"); e.printStackTrace(); } catch ( IllegalAccessException e ) { System.err.println("Unable to access logger factory: " + factoryName + ", using default"); e.printStackTrace(); } catch ( ClassNotFoundException e ) { System.err.println("Unable to locate logger factory class: " + factoryName + ", using default"); e.printStackTrace(); } } }
通过代码我们可以清晰的看到factoryName一定是空的,因为我们压根就没在web.xml中配置factoryName.
所以里面的方法一定不执行。
直接返回。
接下来进入到Dispatcher dispatcher = init.initDispatcher(config);
初始化并创建Dispatcher
Dispatcher是struts2的核心类,完成大部分任务调度,所有的请求共享这一实例。
public Dispatcher initDispatcher( HostConfig filterConfig ) { Dispatcher dispatcher = createDispatcher(filterConfig); dispatcher.init(); return dispatcher; }
通过代码也可以看到Dispatcher是先创建,然后初始化。
它的创建很简单
private Dispatcher createDispatcher( HostConfig filterConfig ) { Map<String, String> params = new HashMap<String, String>(); for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); ) { String name = (String) e.next(); String value = filterConfig.getInitParameter(name); params.put(name, value); } return new Dispatcher(filterConfig.getServletContext(), params); }
把web.xml 中所有的配置信息取出来,放入一个hashmap中,然后存入Dispatcher中。就这样,完了
然后进入初始化,这个有点点复杂
public void init() { if (configurationManager == null) { configurationManager = createConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME); } try { init_DefaultProperties(); // [1] init_TraditionalXmlConfigurations(); // [2] init_LegacyStrutsProperties(); // [3] init_CustomConfigurationProviders(); // [5] init_FilterInitParameters() ; // [6] init_AliasStandardObjects() ; // [7] Container container = init_PreloadConfiguration(); container.inject(this); init_CheckConfigurationReloading(container); init_CheckWebLogicWorkaround(container); if (!dispatcherListeners.isEmpty()) { for (DispatcherListener l : dispatcherListeners) { l.dispatcherInitialized(this); } } } catch (Exception ex) { if (LOG.isErrorEnabled()) LOG.error("Dispatcher initialization failed", ex); throw new StrutsException(ex); } }
通过代码可以看到,初始化做了很多事,首先是创建configurationManager
protected ConfigurationManager createConfigurationManager(String name) { return new ConfigurationManager(name); }
直接new一个configurationManager出来。默认的名称就是struts
初始化属性读取的类
private void init_DefaultProperties() { configurationManager.addContainerProvider(new DefaultPropertiesProvider()); }
以下所有的都一样,将所有的provider初始化,所有的Provider实现类都实现了ConfigurationProvider这个接口。
ConfigurationProvider这个接口又干嘛呢?
public interface ConfigurationProvider extends ContainerProvider, PackageProvider { }
通过代码可以看到核心不在这里,在ContainerProvider和PackageProvider,
这里需要说的是ContainerProvider是容器的初始化,PackageProvider是包的初始化.
什么是容器呢?在struts2中constants/properties配置的信息就是容器的相关信息
PackageProvider就是包的信息,比如我们的struts.xml
回到初始化代码中,DefaultPropertiesProvider就是提供了一个读取默认的struts.properties的实现类。
好了,继续初始化操作。
初始化init_TraditionalXmlConfigurations
private void init_TraditionalXmlConfigurations() { String configPaths = initParams.get("config"); if (configPaths == null) { configPaths = DEFAULT_CONFIGURATION_PATHS; } String[] files = configPaths.split("\\s*[,]\\s*"); for (String file : files) { if (file.endsWith(".xml")) { if ("xwork.xml".equals(file)) { configurationManager.addContainerProvider(createXmlConfigurationProvider(file, false)); } else { configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext)); } } else { throw new IllegalArgumentException("Invalid configuration file name"); } } }
这里提供了俩种初始化配置文件的方法,当然他也提供了选择String configPaths = initParams.get("config");
但是我们在web.xml中没配置,所有默认的一定是struts,而不是xwork
protected XmlConfigurationProvider createStrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) { return new StrutsXmlConfigurationProvider(filename, errorIfMissing, ctx); }
configPaths = DEFAULT_CONFIGURATION_PATHS;
这里我们可以得到证明
private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
继续往里面看,我们看到
public StrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) { super(filename, errorIfMissing); this.servletContext = ctx; this.filename = filename; reloadKey = "configurationReload-"+filename; Map<String,String> dtdMappings = new HashMap<String,String>(getDtdMappings()); dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.0//EN", "struts-2.0.dtd"); dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1//EN", "struts-2.1.dtd"); dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN", "struts-2.1.7.dtd"); dtdMappings.put("-//Apache Software Foundation//DTD Struts Configuration 2.3//EN", "struts-2.3.dtd"); setDtdMappings(dtdMappings); File file = new File(filename); if (file.getParent() != null) { this.baseDir = file.getParentFile(); } }
加入了struts配置文件的验证dtd,在后续会讲
完成了struts配置文件的初始化,继续初始化
init_LegacyStrutsProperties
private void init_LegacyStrutsProperties() { configurationManager.addContainerProvider(new LegacyPropertiesConfigurationProvider()); }
LegacyPropertiesConfigurationProvider这个初始化又干嘛呢?这个初始化主要完成除去上面初始化剩下的其他配置信息想初始化。
init_CustomConfigurationProviders();这个初始化很关键
以上的初始化都说初始化struts框架的配置信息,而这个初始化就是初始化我们在开发中写的配置文件
private void init_CustomConfigurationProviders() { String configProvs = initParams.get("configProviders"); if (configProvs != null) { String[] classes = configProvs.split("\\s*[,]\\s*"); for (String cname : classes) { try { Class cls = ClassLoaderUtil.loadClass(cname, this.getClass()); ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance(); configurationManager.addContainerProvider(prov); } catch (InstantiationException e) { throw new ConfigurationException("Unable to instantiate provider: "+cname, e); } catch (IllegalAccessException e) { throw new ConfigurationException("Unable to access provider: "+cname, e); } catch (ClassNotFoundException e) { throw new ConfigurationException("Unable to locate provider class: "+cname, e); } } } }
通过代码可以看到,通过类加载器加载上来,然后放入configurationManager中。
private void init_AliasStandardObjects() { configurationManager.addContainerProvider(new BeanSelectionProvider()); }
这个初始化是初始化扩展框架的插件信息。
然后初始化一个容器
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; }
struts2的容器用来实现依赖注入和控制反转,定义如下
public interface Container extends Serializable { /** * Default dependency name. */ String DEFAULT_NAME = "default"; /** * Injects dependencies into the fields and methods of an existing object. */ void inject(Object o); /** * Creates and injects a new instance of type {@code implementation}. */ <T> T inject(Class<T> implementation); /** * Gets an instance of the given dependency which was declared in * {@link com.opensymphony.xwork2.inject.ContainerBuilder}. */ <T> T getInstance(Class<T> type, String name); /** * Convenience method. Equivalent to {@code getInstance(type, * DEFAULT_NAME)}. */ <T> T getInstance(Class<T> type); /** * Gets a set of all registered names for the given type * @param type The instance type * @return A set of registered names */ Set<String> getInstanceNames(Class<?> type); /** * Sets the scope strategy for the current thread. */ void setScopeStrategy(Scope.Strategy scopeStrategy); /** * Removes the scope strategy for the current thread. */ void removeScopeStrategy(); }
未完待续
发表评论
-
struts源码之十
2012-12-16 20:53 1434ActionMapping创建完成,就开始执行exece方法。 ... -
struts源码之九
2012-12-16 16:11 1871strtsu2完成request的封装后,就创建ActionM ... -
struts源码之八
2012-12-16 15:04 1542创建完成ActionContext后,strtus2将当Dis ... -
struts源码之七
2012-12-16 14:37 1162struts2一个请求的处理过程分析 strtus2的 ... -
Struts2_ValueStack,OGNL详解
2012-12-15 22:24 10036引言: 闲话不多说,最近项目结束,天天泡在CSDN论坛上,不乏 ... -
struts源码之六
2012-12-15 22:05 1066struts2请求核心流程图如下: 粗略的化了一下 ... -
struts源码之五
2012-12-15 20:35 966struts2请求流程一个简图。如下图所示 只画出了前半部分 ... -
struts源码之四
2012-12-14 23:01 1058初始化Dispatcher完成, init.init ... -
struts源码之二
2012-12-14 22:03 1037struts2初始化静态流程如下: 详细描述 ... -
struts源码之一
2012-12-14 21:59 1366Struts2架构图 Struts2部分类介绍 ... -
Struts2中,radio标签的默认选中问题
2011-10-28 08:59 1068在Struts2中,radio标签可以使用一个list来输 ... -
struts2的itrator循环使用
2011-09-21 11:20 1086下拉框的输出 <s:iterator value=&qu ... -
Struts2通用的Action配置
2010-09-02 17:15 1650<action name="*_*" ... -
struts2的Result配置
2010-08-12 15:38 1265在struts-default.xml <resu ... -
Struts2概述
2010-07-23 15:29 1130Struts2其实并不是一个陌 ...
相关推荐
在Eclipse中关联Struts2.1.8源码,可以帮助开发者更好地理解和调试代码。步骤包括: - 下载Struts2.1.8的源码包。 - 在Eclipse中,右键点击项目,选择"Build Path" -> "Configure Build Path" -> "Libraries" -> ...
struts源码包,解压后会有一个src文件夹,此文件夹下的就是struts的源码。
孙卫琴 struts 源码 孙卫琴 struts 源码 孙卫琴 struts 源码
3. **插件体系**:Struts2支持丰富的插件,如Struts2-convention插件可以实现自动映射Action和方法,Struts2-dojo-plugin则提供了与Dojo库的集成,便于创建富客户端应用。 4. **OGNL(Object-Graph Navigation ...
通过深入研究Struts源码,我们可以了解到框架如何处理请求、执行业务逻辑以及如何将数据呈现给用户。这对于提升Java Web开发技能,理解MVC模式,以及进行性能优化都有着极大的帮助。同时,熟悉源码也有助于开发者更...
本项目源码提供了一个基础的Struts2应用程序实例,对于初学者来说,这是一个很好的学习资源,可以深入理解Struts2的工作原理和架构。 Struts2的核心组件包括: 1. **Action类**:Action类是业务逻辑的载体,它是...
这篇博文“Struts2源码解读”深入剖析了Struts2的核心机制,帮助开发者更好地理解和利用这个框架。源码分析是提升编程技能和解决问题的关键,特别是对于复杂的框架如Struts2,理解其内部工作原理能够帮助我们优化...
Struts2 源码分析 Struts2 是一个基于MVC 模式的Web 应用程序框架,它的源码分析可以帮助我们更好地理解框架的内部机制和工作流程。下面是Struts2 源码分析的相关知识点: 1. Struts2 架构图 Struts2 的架构图...
深入理解Struts2的源码对于提升Java Web开发技能,尤其是在面试中讨论底层实现时,具有非常重要的价值。 首先,我们来看看Struts2的核心组件和设计理念: 1. **Action**:在Struts2中,Action类是业务逻辑处理的...
通过阅读Struts2的源码,我们可以深入了解框架如何处理请求、如何调度Action以及如何应用拦截器来扩展功能。这有助于开发者更好地定制和优化他们的应用程序,提高代码质量和性能。在实际开发中,对源码的理解能帮助...
深入学习Struts2的源码,有助于理解其运行机制,从而更好地优化代码、调试问题,甚至开发自己的扩展。对于Java Web开发者来说,掌握Struts2的基本原理和使用技巧,能够显著提高开发效率和应用质量。
孙卫琴 struts 源码 孙卫琴 struts 源码 孙卫琴 struts 源码 103m
3. **org.apache.struts.util**:包含了一些工具类和辅助类,比如国际化(`MessageResources`)、请求处理(`RequestUtils`)等。 4. **org.apache.struts.taglib**和**org.apache.struts.taglib.html**: 这些是Struts...
3. **拦截器(Interceptors)**:拦截器是Struts2的一大亮点,它们在Action调用前后执行,可以实现如日志、事务管理、权限控制等功能,提高了代码的可复用性。 4. **结果类型(Result Types)**:框架支持多种结果...
本资源包含了Struts的三个不同版本的jar包和源码包:struts-2.3.37-all.zip、struts-2.5.20-all.zip以及struts-1.3.10-all.zip,分别对应了Struts 2的2.3.37版本、2.5.20版本和Struts 1的1.3.10版本。下面将详细讲解...
通过对Struts 1.2.9源码的深入学习,开发者可以了解Web应用的典型开发流程,掌握如何有效地组织和管理复杂的业务逻辑,以及如何优雅地处理用户交互。虽然Struts 1已逐渐被Struts 2和Spring MVC等更新框架替代,但它...
在深入理解Struts2的工作原理时,源码分析是必不可少的步骤。Struts2的核心设计理念和设计模式相比Struts1.x有了显著的变化,这使得它成为一个独立且成熟的框架。 首先,Struts2的架构基于WebWork的核心,这意味着...
在深入理解Struts 2的源码之前,我们需要先了解其核心概念和组件。 1. **Action类与ActionMapping** Struts 2的核心是Action类,它是业务逻辑处理的中心。每个Action类对应一个用户请求,处理后返回一个Result。...
STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析STRUTS2源码解析...
通过深入学习OGNL的源码,开发者可以更好地定制和优化Struts2应用,提升性能,增强安全性,并能解决遇到的特定问题。这是一项值得投入时间和精力的任务,特别是对于那些希望在Web开发领域有深入理解的人来说。