strus2启动和请求过程浅析

来源:互联网 发布:视觉对位系统算法 编辑:程序博客网 时间:2024/06/05 03:56

从点击服务器(这里说到的服务器为tomcat)的start来启动服务,到对服务器发出请求,中间经历了一个怎样的过程?

启动流程:
WEB服务器启动:
1- 加载解析 $CATALINA_HOME/conf/web.xml
2-加载每个WEB app 下的 web.xml
3-对于struts2框架,在web.xml中,会配置拦截器,如下。这时候会初始化 StrutsPrepareAndExecuteFilter类

<filter>        <filter-name>struts2</filter-name>        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>    </filter>    <filter-mapping>        <filter-name>struts2</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>

4-在StrutsPrepareAndExecuteFilter类中的init方法中初始化struts2的配置文件:

public void init(FilterConfig filterConfig) throws ServletException {        InitOperations init = new InitOperations();        Dispatcher dispatcher = null;        try {            FilterHostConfig config = new FilterHostConfig(filterConfig);             init.initLogging(config);  //日志相关            dispatcher = init.initDispatcher(config);//配置文件初始化            init.initStaticContentLoader(config, dispatcher);            prepare = new PrepareOperations(dispatcher);            execute = new ExecuteOperations(dispatcher);            this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);            postInit(dispatcher, filterConfig);        } finally {            if (dispatcher != null) {                dispatcher.cleanUpAfterInit();            }            init.cleanup();        }    }

5:跟踪代码,在Dispatcher类中的init方式中,初始化具体的配置文件

public void init() {        if (configurationManager == null) {            configurationManager = createConfigurationManager(DefaultBeanSelectionProvider.DEFAULT_BEAN_NAME);        }        try {            init_FileManager();            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_CheckWebLogicWorkaround(container);            if (!dispatcherListeners.isEmpty()) {                for (DispatcherListener l : dispatcherListeners) {                    l.dispatcherInitialized(this);                }            }            errorHandler.init(servletContext);        } catch (Exception ex) {            if (LOG.isErrorEnabled())                LOG.error("Dispatcher initialization failed", ex);            throw new StrutsException(ex);        }    }

[1] – init_DefaultProperties()
位置:struts-core-2.3.32.jar -> org/apache/struts2/default.properties
作用:用于配置Struts2常量的默认值

[2]–init_TraditionalXmlConfigurations()
这里会初始话三个配置文件:

private static final String DEFAULT_CONFIGURATION_PATHS = “struts-default.xml,struts-plugin.xml,struts.xml”;

即:struts-default.xml,struts-plugin.xml,struts.xml
struts-default.xml
位置: struts-core-2.3.32.jar 类路径的根路径下
作用:Struts2核心配置
struts-plugin.xml
作用:strut2插件的配置文件
struts.xml
位置:用户类路径的根路径 /src
作用:用户编写的业务处理映射(Action)
[3]–init_LegacyStrutsProperties()
位置:用户类路径的根路径 /src
作用:配置Struts2的常量(非必须)
[5]–init_CustomConfigurationProviders()
用于配置 struts.custom.properties
位置:用户类路径的根路径 /src
作用:配置用户自定义常量

启动流程小结:

加载解析 $CATALINA_HOME/conf/web.xml(tomcat)
初始化 StrutsPrepareAndExecuteFilter
然后按序加载下面配置文件

default.properties,struts-default.xml, struts-plugin.xml,struts.xml,struts.properties,struts.custom.properties

请求流程
当求服务器发出请求的时候,首先会被StrutsPrepareAndExecuteFilter类的doFilter方法拦截:

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) req;        HttpServletResponse response = (HttpServletResponse) res;        try {            if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {                chain.doFilter(request, response);            } else {                prepare.setEncodingAndLocale(request, response);                prepare.createActionContext(request, response);                 prepare.assignDispatcherToThread();                request = prepare.wrapRequest(request);                ActionMapping mapping = prepare.findActionMapping(request, response, true);//获取是否有相应的action                if (mapping == null) { //对于静态资源的处理                    boolean handled = execute.executeStaticResourceRequest(request, response);                    if (!handled) {                        chain.doFilter(request, response);                    }                } else {                    //有相应的action时                    execute.executeAction(request, response, mapping);                }            }        } finally {            prepare.cleanupRequest(request);        }    }

然后调用响应的拦截器:

if (interceptors.hasNext()) { //这里会被反复的调用,直到所有的拦截器都被调用完,然后执行相应的action方法                final InterceptorMapping interceptor = interceptors.next();                String interceptorMsg = "interceptor: " + interceptor.getName();                UtilTimerStack.push(interceptorMsg);                try {                                resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this);                            }                finally {                    UtilTimerStack.pop(interceptorMsg);                }            } else {                resultCode = invokeActionOnly();            }