整合三大框架
两种方式:1. 使用配置文件(都保留) ;2. 使用注解(不在保留Struts和Hibernate的配置文件)
整合1
0 回顾
1 环境
JAR包:
-
Struts2:解压包的lib目录struts-2.3.24\apps\struts2-blank\WEB-INF\lib\下所有包(log4j日志2个可删除),javassist包会有冲突
-
struts2-convention-plugin-2.3.24.jar ----Struts2的注解开发包。
-
struts2-json-plugin-2.3.24.jar ----Struts2的整合AJAX的开发包(很少用了)
-
struts2-spring-plugin-2.3.24.jar ----Struts2的整合Spring的开发包
-
-
Hibernate包:
-
开发必须Jar包,解压lib\Require目录下
-
mysql或其他数据库驱动
-
日志记录:
-
Struts2和Hibernate都引入了一个相同的jar包(javassist包),删除版本低的一个
-
其他数据源如C3P0:解压下/lib/option/c3p0/下的包
-
-
Spring4包:
- 基础4核心+2日志(IOC)
- AOP的包:联盟+aspectj+spring-aop+spring-aspects
- JDBC+tx:事务
- Test:测试
- Web:web开发
- 整合Hibernate:spring-orm
配置文件
-
Struts2:web.xml配置核心过滤器;Struts.xml配置访问映射
-
Hibernate:hibernate.cfg.xml配置文件和其他映射文件;删除那个与线程绑定的session
-
Spring4:web.xml配置核心监听器(默认是在web-inf目录下,需要另外配置加载工厂的路径映射);applicationContext.xml工厂配置文件;
<!-- struts 核心过滤器 --> <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> <!-- spring整合web只在启动时加载一次工厂的实现,配置核心的监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--加载文件配置路径,默认在web-inf目录下 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
-
一份日志配置文件
Spring4 & Struts2
-
Spring整合Struts有两种方式,一种是保留Struts自己创建Action,一种是将Action托管给Spring。
-
方式一:Struts自己创建Action,则在action的属性,可以引入Struts整合spring的插件包,实现属性按名称自动注入,不需要再使用WebApplicationContextUtils来获取工厂进行后续操作。
// WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); // CustomerService customerService = (CustomerService) applicationContext.getBean("customerService"); --------------------- //整合后Spring按名称自动注入 private CustomerService customerService2; public void setCustomerService(CustomerService customerService) { this.customerService2 = customerService; }
-
方式二:Action的创建由Spring进行控制,此时同样需要引入整合的插件包。Action的属性也需要在Bean中进行手动注入(xml或注解)。这时,Struts配置Action的class不再使用全限定名,而是直接使用Spring工厂中Action的ID即可。这种方式一是方便管理,二是方便对Action进行AOP的增强。值得注意的是,Spring默认创建的Bean是单例的,对于Action最好加上prototype
<action name="customer_*" class="customerAction" method="{1}"> <result name="saveUI">/jsp/customer/add.jsp</result> </action> <!-- 将action交给Spring管理,需要手动注入属性 --> <bean id="customerAction" class="com.leehao.ssh.web.action.CustomerAction" scope="prototype"> <property name="customerService" ref="customerService"></property> </bean> <bean id="customerService" class="com.leehao.ssh.service.impl.CustomerServiceImpl" />
Spring4 & Hibernate
首先将Service和Dao交给Spring进行托管,设置Bean和对应的属性注入。
然后,完成数据库与实体的映射,Hibernate的配置及映射文件配置等。
Spring 整合Hibernate
Spring提供了一个orm的jar包,封装了对整合Hibernate的支持。在原始的Hibernate使用中,需要使用配置文件加载器,来加载配置文件获得SessionFactory,从而获得数据库的相关连接进行操作。
引入Spring 的ORM支持后,可以在Spring中执行加载配置文件,获得SessionFactory的过程。
<!-- 将Hibernate交给Spring管理 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 加载Hibernate的配置文件 -->
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
在Spring和Hibernate整合后,Spring提供了一个Hibernate的模板类简化Hibernate开发。在使用JDBC时也曾有过类似的模板支持。需要在Spring配置中提供模板注册,在Dao使用时继承HibernateDaoSupport获得Hibernate的模板。
public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {
@Override
public void save(Customer customer) {
System.out.println("Dao save...");
this.getHibernateTemplate().save(customer);
}
}
------------------------------------------------------
<!-- Dao -->
<bean id="customerDao" class="com.leehao.ssh.dao.impl.CustomerDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
将事务交给Spring
使用Spring创建Hibernate的SessionFactory进行管理后,事务也统一交给Spring进行配置管理,可以直接在Service上使用注解。
数据源连接池,这里整合Spring,若没有连接池会启动错误
<!-- 事务托管 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
-------------------------------------------------------------------
@Transactional
public class CustomerServiceImpl implements CustomerService {
整合2
SSH的整合,不再使用Hibernate的配置核心文件,直接将相关配置在Spring创建Hibernate时加载SessionFactory中设置即可。
<!-- 连接池 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 将action交给Spring管理,需要手动注入属性 -->
<bean id="customerAction" class="com.leehao.ssh.web.action.CustomerAction" scope="prototype">
<property name="customerService" ref="customerService"></property>
</bean>
<!-- 将Hibernate交给Spring管理 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 加载Hibernate的配置文件 -->
<!-- 连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 属性设置 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</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>com/leehao/ssh/domain/Customer.hbm.xml</value>
</list>
</property>
</bean>
Hibernate模板操作
-
save(Object obj);
-
update(Object obj);
-
delete(Object obj);
-
查询一个
- get(Class c,Serializable id);
- load(Class c,Serializable id);
-
查询多个
-
List find(String hql,Object… args);
-
List findByCriteria(DetachedCriteria dc);
-
List findByCriteria(DetachedCriteria dc,int firstResult,int maxResults);
-
List findByNamedQuery(String name,Object… args);
SSH整合带来的延迟加载问题
在使用Hibernate中,会产生延迟加载的情况。
-
用load方法查询某一个对象的时候(不常用)
-
查询到某个对象以后,显示其关联对象
使用MVC分层架构时,事务和session的操作在Service层中被Hibernate提供。而一旦到了Controller或者说Action层想调用相关联的延迟加载属性或对象,则会出现session被关闭的情况。Hibernate不提供解决整合的方案。Spring提供了一个过滤器来解决。
<!-- 解决延迟加载问题的过滤器,一定在核心过滤器的前面设置 -->
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>