SSH
即 struts2 + spring + hibernate 三大框架的整合
SSH整合分析
dao層
- spring 管理dao接口(IOC對bean進行實例化,依賴注入等),使用單例
- dao接口使用 spring 提供的 HibernateTemplate 進行開發
- spring 管理 sessionFactory,使用單例
- spring管理數據源,使用c3p0連接池
service層
- 管理 service 接口,使用單例
- 使用spring聲明式事務控制,對service接口進行事務控制
web層
- spring管理action,使用多例
Dao層整合步驟
準備工作
- hibernate的基礎運行包
- spring的基礎運行包
- spring整合hibernate的整合包
- 數據庫的驅動包
- 數據庫連接池的包(c3p0)
- 日誌包
- 單元測試包(junit)
- spring整合單元測試的包
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 加載屬性文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置數據源,使用c3p0連接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 配置sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 依賴dataSource -->
<property name="dataSource" ref="dataSource"/>
<!-- 創建工廠需要加載hibernate映射文件 -->
<property name="configLocations" value="classpath:hibernate/hibernate.cfg.xml"></property>
</bean>
<!-- 配置hibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 會話工廠 -->
<session-factory>
<!-- 數據庫方言,根據數據庫選擇 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!--爲了方便調試是否在運行hibernate時在日誌中輸出sql語句 -->
<property name="hibernate.show_sql">true</property>
<!-- 是否對日誌中輸出的sql語句進行格式化 -->
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">none</property>
<!-- 事務管理 -->
<!-- 事務隔離級別 -->
<!-- <property name="hibernate.connection.isolation">4</property> -->
<!-- 配置session綁定本地線程 -->
<!-- <property name="hibernate.current_session_context_class">thread</property> -->
<!-- 使用spring與hibernate整合類SpringSessionContext
由spring管理session,如果進行事務控制,spring將session和線程綁定
如果sessionFactory使用了org.springframework.orm.hibernate5.LocalSessionFactoryBean,默認使用SpringSessionContext,下邊不配置也行
-->
<property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>
<!-- 加載映射文件 -->
<mapping resource="com/mydeertrip/ssh/model/BaseDict.hbm.xml"/>
<mapping resource="com/mydeertrip/ssh/model/CstCustomer.hbm.xml"/>
<mapping resource="com/mydeertrip/ssh/model/CstCustomerDetail.hbm.xml"/>
<mapping resource="com/mydeertrip/ssh/model/SysUser.hbm.xml"/>
</session-factory>
</hibernate-configuration>
applicationContext-dao.xml
<bean id="customerDao" class="com.mydeertrip.ssh.dao.impl.CustomerDaoImpl">
<!-- 依賴HibernateTemplate或SessionFactory -->
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<bean id="customerDetailDao" class="com.mydeertrip.ssh.dao.impl.CustomerDetailDaoImpl">
<!-- 依賴HibernateTemplate或SessionFactory -->
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
spring和junit整合
@RunWith(SpringJUnit4ClassRunner.class)
//spring和junit整合,在這裏加載spring加載文件,創建spring容器
@ContextConfiguration(locations={"classpath:spring/applicationContext.xml","classpath:spring/applicationContext-*.xml"})
public class CustomerDaoImplTest {
@Autowired
private CustomerDao customerDao;
@Test
public void test() {
CstCustomer customer = customerDao.findCustomerById(94l);
System.out.println(customer);
}
}
AOP事務控制
目標對象由spring來管理,spring對目標對象生成代理,注入到action中實現事務控制
事務管理器
負責事務控制,在applictionContext中配置事務管理器的bean
<!-- 事務管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<!-- 依賴sessionFactory -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
事務控制增強
<!-- 事務控制(增強) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 事務定義信息
rollback-for:默認是RuntimeException,纔去回滾
-->
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="find*" propagation="SUPPORTS" read-only="true" />
<tx:method name="get*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
</tx:advice>
aop配置
<!-- aop配置 -->
<aop:config>
<!--pointcut的配置必須找到對應的service即目標對象,影響 是否能夠生成代理對象 -->
<aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.itcast.crm.service.impl.*.*(..))"/>
</aop:config>
Web層整合步驟
準備工作
整合步驟
- 在項目中添加 spring 和 struts整合的插件包 struts2-spring-plugin.jar
打開struts2-spring-plugin.jar包中的struts-plugin.xml文件,其中有一個配置,是實例化action的配置
配置如下<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" /> <!-- Make the Spring object factory the automatic default --> <constant name="struts.objectFactory" value="spring" />
該配置將action的創建改爲由:org.apache.struts2.spring.StrutsSpringObjectFactory創建,創建邏輯改爲:先將action的beanName從spring容器中查找,spring容器中沒有,再有strtus創建
在spring的 applicationContext.xml 配置文件中配置一個bean
<!-- spring與struts整合,action由spring創建 --> <bean id="springstruts" class="com.mydeertrip.action.SpringStrtusAction" />
在struts的配置文件中配置action的請求響應
<!-- spring與struts整合,此處class是action在applicationContext容器中的id名稱 --> <action name="spring" class="springstruts" method="test"> <result name="success" type="dispatcher"> /jsp/test.jsp </result> </action>
- web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>crm_ssh0120</display-name>
<!-- 監聽器 -->
<listener>
<!-- 默認從/WEB-INF/applicationContext.xml加載配置文件 -->
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- spring配置文件 可以採用加載多個文件,中間以半角逗號分隔,也可以使用通配符號 -->
<param-value>classpath:spring/applicationContext.xml,classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<!-- OpenSessionInView,解決延遲加載session在web層不可用的問題
將session的生命週期延長到和request一致
-->
<filter>
<filter-name>OpenSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置前端控制器 -->
<!-- 配置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>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
- applicationContext上下文對象和ServletContextListener對象綁定,當創建ServletContext對象時,被監聽器監聽到,此時監聽器創建applicationContext上下文對象,applicationContext的實例對象採取單例管理,與ServletContext綁定,實現單例管理。
- 配置前端控制器
- 配置OpenSessionInView,將session的生命週期延長到和request一致,解決hibernate延遲加載session在web層不可用的問題