Struts2+Spring+Hibernate配置文件形式整合

一. 导入jar包
- 1.1 struts2的包,po图:
- 1.2 spring的jar包,po图:
- 1.3 hibernate的jar包(使用的hibernate5的版本),po图:


2. 在web.xml中的配置
- 2.1 struts2的核心过滤器配置
<!-- struts2的核心过滤器 -->
<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>
- 2.2 在web.xml中spring的配置文件加载方式
原因:当请求进入到对应action中时,需要通过new ClassPathXmlApplicationContext这个对象来加载spring的配置文件,每次都会耗费很多资源,所以spring给出了一个解决方案,通过在web.xml配置ContextLoaderListener这个监听器类,一次性将xml加载到内存中,这样可以避免多次的加载配置文件。
web.xml代码:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 因为这个类是默认加载的WEB-INF目录下的配置文件,所以需要更改加载路径 .才能拿到注入的对象-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
具体action代码:
/* 每次进入action都会去加载配置文件 */
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
CustomerService customerService = (CustomerService) ac.getBean("customerService");
customerService.save(customer);
优化过后的重构代码:
/* 使用spring提供的类,简化获取对象的过程,提高效率 */
WebApplicationContext web = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext());
CustomerService customerService = (CustomerService) web.getBean("customerService");
customerService.save(customer);
2. 配置文件的编写
- Struts2的配置文件:
PS:这种方式是由struts来管理action对象。
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="base" namespace="/customer" extends="struts-default">
<!-- 通配符练习 -->
<action name="save" class="cn.eudask.web.action">
<result>/success.jsp</result>
</action>
</package>
</struts>
- spring的配置文件(完全抛弃掉hibernate.cfg.xml文件,但是映射文件还需要):
- 配置c3p0连接池(数据源)
<!-- 将hibernate的环境交给spring管理 -->
<!-- 配置一个数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///spring?characterEncoding=utf-8"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
- 配置hibernate的相关属性:
<!-- 给sessionFactory 注入一个hibernate的配置文件 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 配置文件映射的方式 -->
<property name="mappingResources">
<list>
<value>cn/eduask/domain/customer.hbm.xml</value>
</list>
</property>
</bean>
- PS:如果是mysql 5.0的数据库版本,需要将方言配置为MySQL5InnoDBDialect,指定版本是5的。
- LocalSessionFactoryBean:这个类是spring提供的在web包中的用于整合hibernate的类,里面包含了SessionFactory的属性。
- HibernateTemplate需要一个LocalSessionFactoryBean对象,通过源码可以看出,HibernateTemplate是可以通过setter方法注入SessionFactory对象,使对象拥有这个实例的。所以,在DAO层需要提供HibernateTemplate的setter方法,便可以获得HibernateTemplate对象。
- HibernateTemplate源码:
//源码中定义的一个SessionFactory类型变量
private SessionFactory sessionFactory;
/**
* Set the Hibernate SessionFactory that should be used to create
* Hibernate Sessions.
* 通过setter方法给sessionFactory变量注入的对象。
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
- 还需要将事务交给spring处理,使用spring提供的HibernateTransactionManager,针对于hibernate的事务管理器。配置了事务后才能拥有读写权限。
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置事务通知 -->
<!-- <tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice> -->
<!-- 配置事务切面 -->
<!-- <aop:config>
<aop:pointcut expression="execution(* cn.eduask.service.impl.CustomerServiceImpl.*(..))" id="pt"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config> -->
- DAO层中的java测试代码
private HibernateTemplate backHibernateTemplate;
public void setBackHibernateTemplate(HibernateTemplate backHibernateTemplate) {
this.backHibernateTemplate = backHibernateTemplate;
}
@Override
public void save(Customer cust) {
backHibernateTemplate.save(cust);
}
- web层中的action的java测试代码
/* 由struts2管理action對象注入service层对象的方式 */
/*private CustomerService customerService;
public void setCustomerService(CustomerService customerService) {
this.customerService = customerService;
}*/
//对象还是由struts管理
这样就基本完成了SSH的配置。
缺陷:虽然这样可以跑通,但是action的对象还是由struts在管理,这样只是完成了单向的整合,所以经过优化,将action的对象也交由spring管理
将Action对象的管理交给spring管理的方式
导入spring提供的整合struts的插件jar包

- spring.xml的更改。将Action的对象放进SpringIOC中。然后将service对象注入到action中。
<bean id="customerAction" class="cn.eduask.web.action.CustomerAction" scope="prototype">
<property name="custService" ref="customerService"></property>
</bean>
PS:scope:由于一个用户的请求是多种的,所以action的对象也不可以是单例的,默认是single单例的,需要修改为多例的prototype多例属性。
2. struts.xml的更改。
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="base" namespace="/customer" extends="struts-default">
<!-- class就需要对应bean的ID -->
<action name="save" class="customerAction">
<result>/success.jsp</result>
</action>
</package>
</struts>
- java测试代码:
/* 开发中推荐使用。使用spring來管理action對象 */
private CustomerService custService;
public void setCustService(CustomerService custService) {
this.custService = custService;
}