1、具体的环境为

MyEclipse 8.5以及自带的tomcat

spring3.0.5

struts2.3.15.1

mybatis3.0.5

2、想弄明白的一些问题

tomcat集成spring,那么spring是如何启动的?

spring是如何读取配置文件的?

spring是如何处理依赖关系的?

应该说所有的bean都是spring实例化的,那么Action的实例是如何产生的?

3、spring是如何启动的?

了解了tomcat的启动过程(容器engine-host-context-wrapper一级一级启动,并且通过事件如ContextConfig等来读取各自应用的web.xml来初始化context),
读了web.xml中的配置,spring也是通过事件来启动的,配置如下:

    <listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener> <listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

注意的是,如果配置了Log4jConfigListener,则Log4jConfigListener的配置要先于ContextLoaderListener的配置(spring3.0.5源码注释得知)。

4、spring启动后做了哪些事情?

通过debug3.0.5的源码,spring解析所有的配置文件,配置文件路径可以如下配置:

    <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>

然后,spring可以得到该应用共有多少个bean(如现在的项目,大概是200+个)

这里,spring还会解析所有的*Sql.xml文件,得到所有的statement mapper
.
.
.

5、Action的实例是如何产生的?也是spring进行管理的吗?

首先Action的实例化不是由spring管理的,因为默认spring产生的实例都是单例的,而Action为了避免多线程产生的不一致,是多例的。

Action的作用是通过Filter机制来实现的:

    <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>

这样所有的请求都会经过这个filter,而如果url是以.action(可在struts.properties中配置)结尾的,则会根据struts*.xml文件中的映射关系new出一个Action
进行处理。

5.1、

首先web application启动时,在初始化spring后,会调用org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(FilterConfig filterConfig) throws ServletException方法,在Dispatcher.java的init方法中会读取解析struts*xml配置文件:

   /**
* Load configurations, including both XML and zero-configuration strategies,
* and update optional settings, including whether to reload configurations and resource files.
*/
public void init() { if (configurationManager == null) {
configurationManager = createConfigurationManager(BeanSelectionProvider.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);
}
}
} catch (Exception ex) {
if (LOG.isErrorEnabled())
LOG.error("Dispatcher initialization failed", ex);
throw new StrutsException(ex);
}
}

然后通过*Provider的register方法来读取各种配置文件(struts默认的以及自己配置的)
如DefaultPropertiesProvider、XmlConfigrationProvider...

注意:和spring有一点不同,struts的ConfigurationManager只会解析struts.xml这个文件(可以配置指定特定名称),如果我们建立了另外的xml配置文件,
如struts-wms.xml,则需要在struts.xml中如下配置,
<include file="struts-wms.xml"></include>
配置文件的包含关系可以多层级的。

5.2、

在每次请求到来的时候,会调用void org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException这个方法,

        //首先,判断这个请求url是不是在struts2处理的排除范围内,如果是,则继续调用其他filter进行处理
if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
request = prepare.wrapRequest(request);
//根据请求url得到对应的action mapping
ActionMapping mapping = prepare.findActionMapping(request, response, true);
//如果action mapping为空,则调用其他的filter进行处理
if (mapping == null) {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
//否则调用action mapping对应的Action进行处理
execute.executeAction(request, response, mapping);
}
}

一点猜想:
在调用完所有的filter之后,如果是由对应Action处理,则由Action处理完成后,通过向response中设值,交由tomcat处理后返回客户端;
如果不是,如图片/js等静态资源,应该是有Tomcat分派的处理线程调用默认的DefaultServlet返回相应资源。
结论是,不论是不是由Action处理,还是tomcat内部直接处理,只要通过封装了request和response,最后就一定可以通过tomcat的处理返回结果到客户端。。

6、Action中使用到的*Service可以通过@Autowired自动注入,这是通过什么样的机制??

ActionContext会new出对应的Action,那么Action中的字段如*Service是通过什么样的机制注入的?猜想是通过某个Interceptor。
但是,通过在*.java文件中搜索"Autowired.class",结果为0,意识到*Service的注入可能不是通过Interceptor。

在通过debug查看StrutsActionProxy中的DefaultActionInvocation字段中的*Action示例,发现*Service都是实例化过后的。

现在重点是弄明白StrutsActionProxy是如何实例化的?
通过这个类Object com.opensymphony.xwork2.spring.SpringObjectFactory.buildBean(String beanName, Map<String, Object> extraContext, boolean injectInternal) throws Exception
来实例化Action并注入*Service的,其中会得到spring的BeanFactory的实现进而得到所有的由spring管理的*Service。。

Tomcat容器运行struts2+spring+mybatis架构的java web应用程序简单分析的更多相关文章

  1. Java Web 开发利用Struts2+Spring+mybatis写一个用户登录界面以及简单的数据交互

    框架的东西太复杂也难以讲通,直接上代码: 一.首先得配置环境 和导入必要的jar包 有一些重要的如下: Filter文件夹下的SafetyFilter.java   model文件夹下的 Global ...

  2. Spring MVC 架构的java web工程如何添加登录过滤器

    发布到外网的web工程必须添加登录过滤器来阻挡一些非法的请求,即只有登录的用户才能对web工程进行请求,否则无论请求什么资源都需要调整到登录页面进行登录操作.这时就需要用到过滤器,其实非常简单,只需要 ...

  3. 【整理】JavaEE基本框架(Struts2+Spring+MyBatis三层,Struts MVC)之间的关系

    #[整理]JavaEE基本框架(Struts2+Spring+MyBatis三层,Struts MVC)之间的关系 ![关系图解](http://images.cnitblog.com/blog/84 ...

  4. JavaEE基本框架(Struts2+Spring+MyBatis三层,Struts MVC)之间的关系

    郭晨 软件151 1531610114 [整理]JavaEE基本框架(Struts2+Spring+MyBatis三层,Struts MVC)之间的关系 visio文件下载 概述 一个JavaEE的项 ...

  5. Struts2+Spring+Mybatis+Junit 测试

    Struts2+Spring+Mybatis+Junit 测试 博客分类: HtmlUnit Junit Spring 测试 Mybatis  package com.action.kioskmoni ...

  6. struts2 + spring + mybatis 框架整合详细介绍

    struts2 + spring + mybatis  框架整合详细介绍 参考地址: https://blog.csdn.net/qq_22028771/article/details/5149898 ...

  7. 【转】Tomcat中部署java web应用程序

    http://www.blogjava.net/jiafang83/archive/2009/06/02/279644.html 转载:今天给大家介绍怎样在Tomcat5.5.9中部署Java Web ...

  8. 在Tomcat中部署Java Web应用程序

    在Tomcat中部署Java Web应用程序有两种方式:静态部署和动态部署.在下文中$CATALINA_HOME指的是Tomcat根目录. 一.静态部署      静态部署指的是我们在服务器启动之前部 ...

  9. Tomcat中部署Java Web应用程序的方式

    Tomcat中部署Java Web应用程序的几种方式: #PetWeb是工程名 1.在TOMCAT_HOME\conf\server.xml文件的HOST节点中加入 <Context docBa ...

随机推荐

  1. CFX客户端调用报错

    Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unex ...

  2. edm注意细节

    Email Direct Marketing不要有js,css也放在html里面不能有热区,所有的border要设置为0在浏览器里面邮件发送可能会歪掉,可以测试接受后是否歪掉 有点时候表格会有细缝等等 ...

  3. python3 安装scrapy Exception: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/pip/req/req_install.py", line 1006, in check_if_exists解决方法

    错误代码: Exception: Traceback (most recent call last): File , in check_if_exists self.satisfied_by = pk ...

  4. VI编辑器学习笔记

    VIM的使用 VI是Linux系统中的一种编辑器,它的使用方法和界面与Unix平台十分相似,掌握了VIM的特殊,你可以感觉到它强大的功能与高效.Vim 相对来说较小,无论你使用任何Linux系统,你总 ...

  5. input覆盖select实现select可写可选择

    1.有时需要一个select选择框,但是对select选择框希望是既可以选择也可以进行输入.下边的代码就是在select选择框上放了一个input框,覆盖在select上面.实现伪装的select效果 ...

  6. 客户信贷管理&临时授信

    信贷额度的组成:假如某客户信用限额1万:开出销售订单时锁定1万:一旦发货1万,销售订单1万限额释放,变成发货锁定限额1万.一旦开票,发货1万限额释放,应收锁定1万限额.清帐成功,应收释放1万.信用限额 ...

  7. [转]iOS/iphone开发如何为苹果开发者帐号APPID续费

    原文地址:http://blog.sina.com.cn/s/blog_68661bd80101nme6.html 其实相当的简单,这篇内容是给财务看的,有的地方连我自己看了都感觉有点...但如果不详 ...

  8. hadoop工作流引擎之azkaban [转]

    介绍 Azkaban是twitter出的一个任务调度系统,操作比Oozie要简单很多而且非常直观,提供的功能比较简单.Azkaban以Flow为执行单元进行定时调度,Flow就是预定义好的由一个或多个 ...

  9. 一个QMLListView的例子--

    一般人不知道怎么去过滤ListView里面的数据,下面是一个转载的文章:http://imaginativethinking.ca/use-qt-quicks-delegatemodelgroup/ ...

  10. Blackhat EU 2013 黑客大会(Full Schedule for Black Hat USA 2013)

    大会文档下载:https://www.blackhat.com/eu-13/archives.html 此次BH EU 议题整体较水,涉及系统安全.移动安全.网络传输安全.WEB安全.游戏安全等.下面 ...