2021-05-12 14:32:11
SSH整合範例
前言
所謂的SSH,就是表現層使用Struts2,業務邏輯層使用Spring,資料存取層使用Hibernate,好了,廢話不多說,開開啟打,哦,不,是開講開講。
前提,需要你熟悉Struts2,Spring,Hibernate的基本使用。
步驟,第一步,新增繁瑣的Jar包們,第二步:Spring整合Hibernate。第三步:Struts2整合Spring。
-------------------------------------------------不知道起啥名分割線--------------------------------------------------------------------------------
我在這四個檔案中尋找jar包。
① 匯入Struts jar包,struts-2.3.15.3appsstruts2-blankWEB-INFlib下的jar包
上面落了一個Struts整和Spring的關鍵jar包:struts2-spring-plugin-2.3.15.3.jar,上面未列出。(共14個包)
②匯入Spring jar包,一個是核心包:spring-framework-3.2.0.RELEASElibs
另一個是依賴包:
其中,spring-orm.jar就是Spring整合Hibernate的關建包。(共13個包)
注意:若單獨參照Spring,還需引入一個依賴包:com.springsource.org.apache.commons.logging-1.1.1.jar,但是由於前面Struts2引入了commons-logging-1.1.3.jar包,所以不需要再次參照。其實,它們是一樣的程式碼,只是Spring將其改了名字,自己可以檢視程式碼就會發現了。
③匯入Hibernate Jar包
ehcache.jar包是Hibernate的二級快取包,其依賴backport-util-concurrent.jar,和commons-logging.jar包。(共10個包)
Hibernate中也有一個Javassist-3.12.0.GA.jar包,Struts2中已經參照了javassist-3.11.0.GA.jar,所有我替換成了12版本。上面未列出。
④當然,最後還有一個jar包,那就是mysql-connector-java-5.0.8-bin.jar。
到此為止,共新增了38個包,包不再改動。
----------------------------------------情景設定分割線--------------------------------------------------------------------------------------------------
業務:使用者新增
實體類:User(兩個欄位:name和age)
------------------------------[Spring+Hibernate]分割線-----------------------------------------------------------------------------------------------
Spring開始整合Hibernate,眾所周知,這兩個框架都有自己的組態檔,分別是:Spring的applicationContext.xml(名字任意),Hibernate的組態檔與對映檔案hibernate.cfg.xml與【實體類】.hbm.xml檔案。整合的結果就是Hibernate的組態檔消失(當然它的設定資訊跑到了Spring的組態檔中去了)。
程式程式碼:
//DAL層的使用者介面 public interface UserDao { boolean insert(User user); } //DAL層的使用者介面的具體實現 public class UserDaoImpl extends HibernateDaoSupport implements UserDao { @Override public boolean insert(User user) { HibernateTemplate s=this.getHibernateTemplate(); s.save(user); return true; } }
applicationContext.xml檔案設定:(User.hbm.xml不多說,沒區別)
<!-- 使用C3P0得到資料來源--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> </bean> <!-- 使用FactoryBean建立Spring得到 SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 把hibernate.cfg.xml檔案中的設定資訊注入進來,從而可以刪掉組態檔 --> <property name="dataSource" ref="dataSource"></property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="javax.persistence.validation.mode">none</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.current_session_context_class">thread</prop> </props> </property> <property name="mappingLocations" value="classpath:king/domain/User.hbm.xml"></property> </bean> <!-- 目的:建立DAO --> <bean id="userDao" class="king.dao.impl.UserDaoImpl"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- Spring的事務管理之Hibernate,需要注入SessionFactory --> <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 通知 --> <tx:advice id="adviceId" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/> </tx:attributes> </tx:advice> <aop:config> <aop:advisor advice-ref="adviceId" pointcut="execution(* king.dao.impl.*.*(..))"/> </aop:config>
測試程式碼:
@Test public void test1(){ ClassPathXmlApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao user=app.getBean(UserDao.class); User u=new User(); u.setAge(1); u.setName("King"); user.insert(u); app.close(); }
這樣就實現了Spring與Hibernate的整合,去掉了hibernate.cfg.xml檔案,由原來直接操作SessionFactory,Session到現在我們操作Spring提供的類來操作。
解讀:
- 1
之前我們使用Spring的JdbcTemplate時,需要DAL層物件繼承JdbcDaoSupport,而我們整合了Hibernate,就需要DAO物件繼承HibernateDaoSupport。而我們繼承這個類是為了得到HibernateTemplate物件,來運算元據庫,HibernateTemplate使用起來和Session類似,其底層就是採用Session。而資料來源等等各種設定肯定在我們得到HibernateTemplate物件之前啦,所以這時肯定就需要注入【原來寫在hibernate.cfg.xml中的設定資訊】。說到HibernateDaoSupport的注入,要麼注入SessionFactory,要麼注入HibernateTemplate。這裡我們注入SessionFactory。可以在上面的組態檔中看出。
- 2
說一下applicationContext.xml檔案,我們要得到UserDaoImpl物件,需要往裡面注入SessionFactory。我們要得到SessionFactory,需要往裡面注入DataSource與各種設定資訊。這裡的資料來源(連線池)我們採用C3P0。
- 3
說一下UserDaoImpl物件的生成,我們得到的肯定是代理物件,因為下面已經加上了<aop:config></aop:config>標籤,所以是全自動方式的代理物件,是基於介面的JDK代理物件方式生成,當然也可以設定為CGlib生成代理物件,需要新增額外設定<proxy-target-class="true">
- 4
這裡的代理物件的通知就是事務。通過txManager來對目標方法的前後新增【開啟事務】【提交事務/回滾事務等等操作】,然後返回代理物件。這時,我們所有的操作都是在事務之中,只要發生異常,事務就會回滾。這裡是宣告式事務。
- 5
說一下我們加的幾個包的作用。
Spring-orm.jar 它就是Spring整合Hibernate的關鍵,它依賴spring-jdbc.jar包,因為它會用到其中的LobHandler類。
Spring-web.jar 它是讓Tomcat容器載入Spring組態檔的關鍵。因為我們需要容器為我們載入組態檔,建立代理物件。
slf4j-api.jar SLF4J(Simple logging Facade for Java)不是一個真正的紀錄檔實現,而是一個抽象層,它允許你在後台使用任意一個紀錄檔類庫。如果是在編寫供內外部都可以使用的API或者通用類庫,那麼你真不會希望使用你類庫的用戶端必須使用你選擇的紀錄檔類庫。所以我們若要使用log4j,則還需引入slf4j-log4j.jar包。
----------------------------------------[Struts2+Spring]整合分割線-------------------------------------------------------------------
struts.xml:
<struts> <constant name="struts.devMode" value="true"/> <package name="User" namespace="/User" extends="struts-default"> <!-- action的範例由struts來建立 --> <action name="AddUser" class="king.action.UserAction" method="addUser"> <result name="success" type="redirect">/success.html</result> </action> </package> </struts>
web.xml:
<!-- 這兩處設定是Spring為了整合Web,這是因為原來手動載入.xml檔案,現在需要Tomcat啟動載入.xml檔案, 所以需要Spring整合Web,讓Tomcat載入組態檔,來實現注入,生成代理等等各種功能。spring-web.jar包在起作用。 --> <!-- 很多Spring的jar包依賴commons-logging.jar包 Commons-logging.jar的目的是為“所有的Java紀錄檔實現”提供一個統一的介面。 --> <!-- 設定spring組態檔的位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- 如果只設定spring的監聽,則會載入預設的位置:[WEB-INF/applicationContext.xml]切記切記 作用:啟動Web容器時,自動裝配ApplicationContext的設定資訊。 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<!-- 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>
UserAction類:
/** * ActionSupport出自xwork-core.jar * * 疑問:userDao是誰注入的? * 答案:struts2-spring-plugin.jar中的struts-plugin.xml,設定預設的物件工廠為Spring,由Spring進行注入。 * * @author King * */ public class UserAction extends ActionSupport implements ModelDriven<User> { private static final long serialVersionUID = 1885943501464870512L; private User user=new User(); @Override public User getModel() { return user; } private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public String addUser(){ boolean isOk=userDao.insert(user); if(isOk){ return "success"; }else{ return "fail"; } } }
這樣我們就實現了Struts2+Spring的整合,關鍵之處在於web.xml的設定和struts2-spring-plugin.jar中的struts-plugin.xml,兩個組態檔。
解讀:
- 1
Struts2有一系列的組態檔按照一定順序載入 1 :default.propertities 2:struts-default.xml 3:struts-plugin.xml 4 :struts.xml。
而我們引入了struts2-spring-plugin.jar中,其中有struts-plugin.xml,裡面設定了物件工廠由Spring來建立。所以明明這裡的UserAction是Struts2建立的,但是UserDao物件是由Spring注入的,注意:<bean id="userDao"></bean>與程式碼中 private UserDao userDao; 名字要相同,這樣Spring才能注入,否則會出現空指標異常。
- 2
之前我們測試類中是手動載入applicationContext.xml檔案,得到其中的bean,而整合了Struts2,我們發現沒有這個過程了,而Spring照樣正常工作,這是為啥呢?
這就是上面我們設定監聽類<listener-class>ContextLoaderListener</listener-class>的作用:載入applicationContext.xml檔案,所以我們沒有手動載入組態檔而Spring正常工作的原因。你可以看,這個類所屬的包就是spring-web.jar,所以這個包也是整合它們的關鍵。
好了,到現在為止,SSH三大框架整合完畢。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2016-11/137138.htm
相關文章