struts2的启动流程与请求流程

从点击服务器(这里说到的服务器为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();
            }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值