三大框架的整合步骤:
* 新建一个工程
* 把整个工程的编码改变成utf-8
* 把整个jsp页面也改变成utf-8
* 导包
web-inf
lib
struts
hibernate
spring
db
junit
* 建三个src folder
src 存放源代码的
cn.itcast.s2sh0909.struts2.action
cn.itcast.s2sh0909.dao
cn.itcast.s2sh0909.dao.impl
cn.itcast.s2sh0909.service
cn.itcast.s2sh0909.service.impl
cn.itcast.s2sh0909.domain
config 存放所有的配置文件
struts2
hibernate
spring
applicationContext.xml
applicationContext-db.xml
...........
test 存放测试类
cn.itcast.s2sh0909.test
* 在dao和service层相应的包中写接口和类
* 在applicationContext-db.xml文件中写sessionFactory
* 在cn.itcast.s2sh0909.test包中新建一个类SessionFactoryTest,目的是为了测试SessionFactory
是否配置正确
* 写spring的声明式事务处理
* 在spring的配置文件中写dao和service
* 通过savePerson方法测试声明式事务处理
* 编写action
* 编写struts2的配置文件
* 编写web.xml文件
* 测试
二:
* web.xml
* spring容器是以监听器的形式与tomcat整合的
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext.xml</param-value>
</context-param>
说明:
* createContextLoader() 加载spring的web容器
* initWebApplicationContext
* 初始化spring的web容器
* 加载其配置文件
* 当执行完这两个方法以后,就启动spring的web容器了,在spring容器中,单例模式的
bean就被实例化了,所以dao和service层的对象和代理对象就在这个时候产生了
* 以过滤器的形式整合struts2容器
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
当tomcat启动的时候 执行一下代码:
在tomcat启动的时候,干了两件事情:
* 加载了各种配置文件
* 静态注入了一些bean
步骤
* 先找struts的配置文件,会找根据struts2的相关配置查找action的创建方式
* 会去常量struts.objectFactory查找到底是由哪个类创建了action
* 会去struts-default.xml,struts-plugin.xml,struts.xml文件去找struts.objectFactory
* 哪个配置文件加载在最后,哪个决定
* 最后在struts和spring整合的包中找到了struts-plugin.xml文件
<beantype="com.opensymphony.xwork2.ObjectFactory" name="spring"class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
<constantname="struts.objectFactory" value="spring" />
* 由上述的内容可以知道,action是由StrutsSpringObjectFactory创建的,而该类继承了SpringObjectFactory
三:s2sh整合以后,spring管理事务,事务的范围
* 如果当前执行的方法没有事务环境,当this.getHibernateTemplate这个方法执行完以后
session立即关闭
* 如果当前执行的方法有事务环境,当事务环境的方法被调用完毕以后session关闭
在web.xml文件中:
做了opensessioninview的配置
从下边的代码可以看出来:
当提交一个请求时,OpenSessionInView中已经把session
开启了,在response以后才要关闭session
也就意味着有了opensessioninview模式以后,session的打开被提前
了,session的关闭被延后了,这样就解决了懒加载引起的异常
两个过滤器,OpenSessionInview必须在struts2的过滤器之前
缺点:
因为session的关闭被延后了,而hibenate的一级缓存在session
中,所以会导致大量的缓存中的数据被长时间停留在内存中
*********************************************************************
创建ActionContext做的工作
* 在actionContext中存在一个Map<String,Object>
* ValueStack stack =dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
通过静态注入创建ValueStack的实现类:OgnlValueStack,也就意味着在创建actionContext的时候,值栈就被创建了
* ValueStack中的map栈和ActionContext中的Map是一样的
* 通过ActionContext.setContext(ctx);就把actionContext放入到ThreadLocal中,这样数据就安全了
*************************************************************************
ActionProxy的创建
* ActionProxy proxy=config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method,extraContext, true, false);
* 在createActionProxy的时候
ActionInvocation inv = newDefaultActionInvocation(extraContext, true);
创建了DefaultActionInvocation
在创建ActionProxy的时候,就已经执行invocation的init方法
invocation的init方法做的事情:
action的创建和所有的拦截器的创建
执行invocation中的inovke方法
* 执行了所有的拦截器
* 执行了当前请求的action
* 执行了结果集