`
wlzjdm
  • 浏览: 26035 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts2的启动过程源码分析

 
阅读更多

 

此文重点分析struts启动的时候加载的配置文件信息:

郑重声明:此篇文章完全是自己经过单步调试、及其自己的理解而写的,其中如有错误之处,还请朋友指点。读者在阅读的时候,如果有问题,还建议去自己探究发现、或者与我交流,不能尽信此文。还有部分的信息是参考网上的,在文章最后备注有参考链接。

我们在XML中配置的就是org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter这个类,这个是进入struts构架的入口,也就是它将struts2嵌入嵌入到我们的工作中。

下面是它的初始化函数,当该函数执行完成之后,也就完成了关于struts2的所有的配置文件的加载。

 

public void init(FilterConfig filterConfig) throws ServletException {
		//InitOperations正如所描述的,里面包含了初始化的操作。
        InitOperations init = new InitOperations();
        try {
			//包装FilterConfig的主机配置
            FilterHostConfig config = new FilterHostConfig(filterConfig);
            init.initLogging(config);
			//其实完成各种配置文件的加载就在这个函数中,详情如下面的解析
            Dispatcher dispatcher = init.initDispatcher(config);
            init.initStaticContentLoader(config, dispatcher);

            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
			this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

            postInit(dispatcher, filterConfig);
        } finally {
            init.cleanup();
        }
    }

 

 现在我们一步一步分析initDispatcherconfig)这个函数

 

 

/**
     * Creates and initializes the dispatcher
     */
    public Dispatcher initDispatcher( HostConfig filterConfig ) {
		/*
首先我们了解一个很重要的类:Dispatcher
正如其帮助文档所写的:A utility class the actual dispatcher delegates most of its tasks to. Each instance of the primary dispatcher holds an instance of this dispatcher to be shared for all requests.
这个类的构造方法:
public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {
        this.servletContext = servletContext;
        this.initParams = initParams;
    }
此处就是构造了这样一个派发对象
*/
        Dispatcher dispatcher = createDispatcher(filterConfig);
		
		/*
		下面的这个函数是初始化配置的入口,请直接看下面init函数的解析
*/
        dispatcher.init();
        return dispatcher;
    } 

 

下面的是org.apache.struts2.dispatcher.Dispatcherinit函数    

 /** Load configurations, including both XML and zero-configuration strategies,
     * and update optional settings, including whether to reload configurations and resource files.
     */
    public void init() {
		//配置管理器,当我们加载完配置之后,由此管理器完成对配置的管理
		/*
在com.opensymphony.xwork2.config.ConfigurationManager中有两个列表变量,就是用来存储各种的配置类:
ContainerProvider的介绍:Provides beans and constants/properties for the Container
private List<ContainerProvider> containerProviders = new CopyOnWriteArrayList<ContainerProvider>();
PackageProvider的介绍:Provides configuration packages.  The separate init and loadPackages calls are due to the need to preserve backwards compatibility with the ConfigurationProvider interface
private List<PackageProvider> packageProviders = new CopyOnWriteArrayList<PackageProvider>();
		*/
    	if (configurationManager == null) {
    		configurationManager = createConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
    	}

        try {
			//下面的七步将完成配置文件的加载

			//org/apache/struts2/default.properties文件的加载
//该配置文件由org.apache.struts2.config. DefaultPropertiesProvider加载(重点留意其中的Register函数)
            init_DefaultProperties(); // [1]

			//完成struts-default.xml,struts-plugin.xml,struts.xml的加载
			// com.opensymphony.xwork2.config.providers. XmlConfigurationProvider中的			register函数将完成XML的解析,详细解析方法可参考源代码
            init_TraditionalXmlConfigurations(); // [2]

			//加载自定义的属性文件:struts.properties
            init_LegacyStrutsProperties(); // [3]

			//加载Web.xml中的配置
            init_CustomConfigurationProviders(); // [5]

			//加载Web.xml中的过滤器参数配置
            init_FilterInitParameters() ; // [6]

//将一个BeanSelectionProvider类追加到ConfigurationManager对象内部的
// ConfigurationProvider队列中
// BeanSelectionProvider主要实现加载org/apache/struts2/struts-messages
            init_AliasStandardObjects() ; // [7]
			
//接下来就开始执行配置文件中的init函数和Register函数
//下面的这个函数会转到:
/*
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;
    }
*/
            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);
        }
    } 

此函数位于:com.opensymphony.xwork2.config. ConfigurationManagerpublic synchronized Configuration 中

		getConfiguration(){//此时会去执行else分支
        if (configuration == null) {
            setConfiguration(createConfiguration(defaultFrameworkBeanName));
            try {
                configuration.reloadContainer(getContainerProviders());
            } catch (ConfigurationException e) {
                setConfiguration(null);
                throw new ConfigurationException("Unable to load configuration.", e);
            }
        } else {
			//看看这个函数的内幕:函数比较长,就单只写一个主要的部分吧
			/*
			……
			if (reload) {
            	for (ContainerProvider containerProvider : containerProviders) {
                	try {
                		containerProvider.destroy();
                	}
                	catch(Exception e) {
                      if (LOG.isWarnEnabled()) {
         LOG.warn("error while destroying configuration provider ["+containerProvider+"]",e);
                            }
                	}
                }
				//重点的也就是这个函数了,它会去执行init和register方法
//此处调用的是com.opensymphony.xwork2.config.impl. //DefaultConfiguration中的重写方法
                packageProviders = configuration.reloadContainer(providers);
				过多的代码此处不写了,只看重要部分:
				ContainerProperties props = new ContainerProperties();
     		   ContainerBuilder builder = new ContainerBuilder();
     		   for (final ContainerProvider containerProvider : providers)
     		   {
					//下面两句就是完成初始化和注册操作
       			     containerProvider.init(this);
       		     containerProvider.register(builder, props);
      			}
			……
*/
            conditionalReload();
        }

        return configuration;
    } 

 至此struts的配置都已经加载完成了。

参考链接:

http://blog.csdn.net/ferry_passion/article/details/7110207

 

 

分享到:
评论

相关推荐

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (1)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...

    Struts原理、开发及项目实施

    Struts原理、开发及项目实施 Holen 2002-9-12 &lt;br/&gt;1、 摘要 2、 关键词 3、 Framework 4、 Struts的起源 5、 Struts工作原理 6、 Struts安装 7、 一个实例 8、 Struts优缺点...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (3)

    一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    全书分4篇,共24章,其中,第1篇为技能学习篇,主要包括Java Web开发环境、JSP语法、JSP内置对象、Java Bean技术、Servlet技术、EL与JSTL标签库、数据库应用开发、初识Struts2基础、揭密Struts2高级技术、Hib锄劬e...

    Eclipse开发入门与项目实践 源代码

    案例6-2 结合Hibernate和Struts实现商务系统身份验证 224 第7章 Eclipse中SWT/JFace开发 237 7.1 安装SWT Designer 237 7.2 SWT/JFace程序基本实现过程 242 案例7-1 SWT/JFace开发初体验 243 7.3 SWT/...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ │ 13.RPC底层通讯原理之Netty线程模型源码分析.wmv │ │ │ ├─14.分库分表之后分布式下如何保证ID全局唯一性 │ │ 14.分库分表之后分布式下如何保证ID全局唯一性.mp4 │ │ │ └─15.大型公司面试必答之...

    JAVA上百实例源码以及开源项目源代码

    Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来...

    JAVA上百实例源码以及开源项目

     Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的注释,对学习有帮助。 Java实现的FTP连接与数据浏览程序 1个...

    《程序天下:J2EE整合详解与典型案例》光盘源码

    2.1.2 MVC模式的处理过程 2.2 Model规范 2.2.1 Model1规范 2.2.2 Model2规范 2.3 使用MVC的优劣 2.3.1 使用MVC模式的好处 2.3.2 使用MVC模式的不足之处 2.4 目前市场上常见的轻量级J2EE开发容器 2.5 小结 第二篇 ...

    Jsp汽车租赁信息管理系统 技术文档.rar

     在Web应用开发中套用现成的Struct框架,可以简化每个开发阶段的工作,开发人员可以更加有针对性地分析应用需求,不必重新设计框架,只需在Struct框架的基础上,设计MVC各个模块包含的具体组件,在编码过程中,可以...

    超级有影响力霸气的Java面试题大全文档

    抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承:  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承...

    java 面试题 总结

    抽象包括两个方面,一是过程抽象,二是数据抽象。 2.继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类...

Global site tag (gtag.js) - Google Analytics