Spring學(xué)習(xí)筆記系列(二)

          Spring學(xué)習(xí)筆記二(2006.1.4)

          1,配置文件的配置頭
          <?xml version="1.0" encoding="UTF-8"?>

          <!--
            - Application context definition for JPetStore's business layer.
            - Contains bean references to the transaction manager and to the DAOs in
            - dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
            -->
          <beans xmlns="    xmlns:xsi="    xmlns:aop="    xmlns:tx="    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                 http://www.springframework.org/schema/tx 這樣寫(xiě)才對(duì)

          2,配置文件可以使用多個(gè)屬性文件
          <!-- Configurer that replaces ${...} placeholders with values from properties files -->
           <!-- (in this case, mail and JDBC related properties) -->
           <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
             <list>
              <value>WEB-INF/mail.properties</value>
              <value>WEB-INF/jdbc.properties</value>
             </list>
            </property>
           </bean>
          類是框架的。
          里面包含兩個(gè)屬性文件,屬性文件里都是“key=value”這種形式的。這樣配置文件里就可以使用屬性文件里的key,使用方法
          ${key},這樣轉(zhuǎn)移出屬性設(shè)置,維護(hù)起來(lái)比較方便。

          3,定義Validator供web層使用,自定義類。
          <bean id="accountValidator" class="org.springframework.samples.jpetstore.domain.logic.AccountValidator"/>
          類里面使用了ValidatorUtils系統(tǒng)類來(lái)進(jìn)行處理。

          4,服務(wù)層的定義。
           PetStoreImpl定義在配置文件中,是自己的類。
           所有的DAO都是它的屬性,注意,DAO是interface,而不是class.
           PetStoreImpl中定義了所有的DAO接口作為屬性,定義了他們的set方法,但是沒(méi)有定義get方法。
           這樣所有的業(yè)務(wù)操作就可以不用管DAO是如何實(shí)現(xiàn)的了,而只管使用這個(gè)PetStoreImpl就好了。

           DAO都是接口這種做法與平時(shí)開(kāi)發(fā)不一樣,我以前使用hibernate生成工具生成的dao都是默認(rèn)好的實(shí)現(xiàn)類。
           而此處的DAO卻都是接口。他們的實(shí)現(xiàn)方法是這樣的:
           interface PetStoreFacade { } //定義所有的業(yè)務(wù)方法。
           interface AccountDao{} //定義所有帳戶的業(yè)務(wù)方法。
           interface CategoryDao{} //定義類別的業(yè)務(wù)方法。
           interface ProductDao{} //定義產(chǎn)品的業(yè)務(wù)方法。
           。。。其他DAO接口,定義自己的業(yè)務(wù)方法。
           class PetStoreImpl implements PetStoreFacade //這個(gè)類就是一個(gè)javabean,操作的都是接口。
           //定義所有DAO接口當(dāng)作自己的屬性。
           //實(shí)現(xiàn)set方法
           //實(shí)現(xiàn)PetStoreFacade 定義的業(yè)務(wù)接口,實(shí)現(xiàn)的時(shí)候調(diào)用DAO接口的方法。

           如果是我自己,那么就會(huì)定義IDAO當(dāng)作接口,因?yàn)閔ibernate插件自動(dòng)生成dao類,容易混淆。
           
          5,配置文件中定義dataSource
           <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${jdbc.driverClassName}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
           </bean>
           可見(jiàn),可以直接使用properties中的key。另外可以將數(shù)據(jù)庫(kù)操作弄成另外一個(gè)配置文件。只要在web.xml中設(shè)置好就可以了,
           <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
             /WEB-INF/dataAccessContext-local.xml  /WEB-INF/applicationContext.xml
            </param-value>
           </context-param>

          6,配置文件中定義事務(wù)管理
          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
           </bean>
           使用了數(shù)據(jù)源作為屬性。

          7,dao具體實(shí)現(xiàn)類。
           JPetStore使用ibatis作為ORM層。所以dao類的定義也都使用了ibatis。
           PetStoreImpl五個(gè)接口接受五個(gè)實(shí)現(xiàn)了對(duì)應(yīng)接口的實(shí)現(xiàn)類。這里的實(shí)現(xiàn)類,
          <bean id="petStore" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
            <property name="accountDao" ref="accountDao"/>
            <property name="categoryDao" ref="categoryDao"/>
            <property name="productDao" ref="productDao"/>
            <property name="itemDao" ref="itemDao"/>
            <property name="orderDao" ref="orderDao"/>
           </bean>
           <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao">
            <property name="sqlMapClient" ref="sqlMapClient"/>
           </bean>
           實(shí)現(xiàn)類,使用ibatis。在配置文件中對(duì)英。
          public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao{
           //實(shí)現(xiàn)了業(yè)務(wù)接口,繼承了ibatis基本類。
           }


          8,ibatis基礎(chǔ)類。
              <!-- SqlMap setup for iBATIS Database Layer -->
           <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
            <property name="configLocation" value="WEB-INF/sql-map-config.xml"/>
            <property name="dataSource" ref="dataSource"/>
           </bean>
           dao實(shí)現(xiàn)類都由他作屬性。
              <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.ibatis.SqlMapAccountDao">
            <property name="sqlMapClient" ref="sqlMapClient"/>
           </bean>

          9,我竟然找不到action對(duì)應(yīng)的mapping在什么地方定義的。
          后來(lái)找到了是petstore-servlet.xml,by default defined in "{servlet-name}-servlet.xml"...
          <!--
             - Spring web MVC servlet that dispatches requests to registered handlers.
             - Has its own application context, by default defined in "{servlet-name}-servlet.xml",
             - i.e. "petstore-servlet.xml" in this case.
             -
             - A web app can contain any number of such servlets.
             - Note that this web app has a shared root application context, serving as parent
             - of all DispatcherServlet contexts.
             -->
           <servlet>
            <servlet-name>petstore</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>2</load-on-startup>
           </servlet>
           原來(lái)是根據(jù)servlet名字命名影射文件的。
           影射文件和配置文件的結(jié)構(gòu)完全一致,也是beans開(kāi)頭的。主要是web層的url影射,
           <beans>
           <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/jsp/spring/"/>
            <property name="suffix" value=".jsp"/>
           </bean>
           ....
           </beans>
           ok,現(xiàn)在把petstore-servlet.xml也放到SpringIDE里察看。

          10,配置文件petstore-servlet.xml
           viewResolver,定義了一個(gè)表現(xiàn)層的基本配置,此bean名字固定。
           屬性viewClass使用了jstl技術(shù)。
           <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/jsp/spring/"/>
            <property name="suffix" value=".jsp"/>
           </bean>

          11,配置文件petstore-servlet.xml
           defaultHandlerMapping使用默認(rèn)的BeanNameUrl影射,具體不太明白。
           <bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

          12,配置文件petstore-servlet.xml
           定義*.do
          <bean name="/shop/addItemToCart.do" class="org.springframework.samples.jpetstore.web.spring.AddItemToCartController">
            <property name="petStore" ref="petStore"/>
           </bean>
           屬性petStore是在applicationContext.xml里定義的,看來(lái)這里也可以使用其他<beans>定義的bean。

          13,*.do類研究
           實(shí)現(xiàn)了Controller,接口public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
           有一個(gè)屬性petstore,是一個(gè)接口PetStoreFacade,包括全部業(yè)務(wù)邏輯接口。
           
          14,首頁(yè)index
           在mapping文件里定義了系統(tǒng)ParameterizableViewController,相當(dāng)于forwardAction。
           <bean name="/shop/index.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
            <property name="viewName" value="index"/>
           </bean>
           而首頁(yè)里大量使用了jstl語(yǔ)言,最重要的地方是所有 a href=, action=,處都使用了<c:url value="/xxxx"/>
           這樣的定義,這樣換域名或者設(shè)置虛擬目錄名,就會(huì)運(yùn)行正常了。例如,
          <center>
          <a href="<c:url value="/shop/viewCategory.do?categoryId=FISH"/>">
          <img border="0" src="../images/sm_fish.gif" /></a>
          <img border="0" src="../images/separator.gif" />
          <a href="<c:url value="/shop/viewCategory.do?categoryId=DOGS"/>">
          <img border="0" src="../images/sm_dogs.gif" /></a>
          <img border="0" src="../images/separator.gif" />
          <a href="<c:url value="/shop/viewCategory.do?categoryId=REPTILES"/>">
          <img border="0" src="../images/sm_reptiles.gif" /></a>
          <img border="0" src="../images/separator.gif" />
          <a href="<c:url value="/shop/viewCategory.do?categoryId=CATS"/>">
          <img border="0" src="../images/sm_cats.gif" /></a>
          <img border="0" src="../images/separator.gif" />
          <a href="<c:url value="/shop/viewCategory.do?categoryId=BIRDS"/>">
          <img border="0" src="../images/sm_birds.gif" /></a>
          </center>

          15, 進(jìn)入首頁(yè)后點(diǎn)左邊的鏈接都指向同一個(gè)viewCategory.do,
           <bean name="/shop/viewCategory.do" class="org.springframework.samples.jpetstore.web.spring.ViewCategoryController">
            <property name="petStore" ref="petStore"/>
           </bean>
           類研究:
           ViewCategoryController implement Controller
           里面只使用了PetStore實(shí)現(xiàn)類的方法,并沒(méi)有DAO對(duì)象。只有Domain對(duì)象。
           很好,把主要的和業(yè)務(wù)相關(guān)的東西都在Controller中展現(xiàn)出來(lái)了,其他輔助的東西都被隱藏了,使得Controller非常簡(jiǎn)潔。
           另外,在業(yè)務(wù)PetStoreImp類中,使用了DAO,這樣就使得后臺(tái)程序也開(kāi)始分層了。
           
           |--層Controller及使用的daomain對(duì)象 /// 第一層
                      |----層PetStoreFacade 接口及他的實(shí)現(xiàn)類PetStoreImpl //第二層
             |-------- 層DAO接口 ,DAO接口實(shí)現(xiàn)類,//第三層
              |------------實(shí)現(xiàn)類中使用的ORM類  //第四層
           層次非常的分明。
              
           daomain符合javabean規(guī)范,并且有些javabean還有自己的public方法。大多數(shù)javabean沒(méi)有必要有public方法。

          16, 點(diǎn)擊分類后,顯示分類中的items,點(diǎn)items可以進(jìn)入viewProduct.do?productId=xxx,來(lái)觀看產(chǎn)品。
           <bean name="/shop/viewProduct.do" class="org.springframework.samples.jpetstore.web.spring.ViewProductController">
            <property name="petStore" ref="petStore"/>
           </bean>
           這是一個(gè)翻頁(yè)功能的Controller。
           沒(méi)弄清楚成功后跳轉(zhuǎn)到什么地方? return new ModelAndView("Product", model);沒(méi)有理解。
           
          public class ModelAndViewextends ObjectHolder for both Model and View in the web MVC framework. Note that these are entirely distinct. This class merely holds both to make it possible for a controller to return both model and view in a single return value.

          Class to represent a model and view returned by a handler used by a DispatcherServlet. The view can take the form of a reference to a View object, or a String view name which will need to be resolved by a ViewResolver object. The model is a Map, allowing the use of multiple data objects keyed by name.

          public ModelAndView(String viewName,
                              Map model)Creates new ModelAndView given a view name and a model.

          Parameters:
          viewName - name of the View to render, to be resolved by the DispatcherServlet
          model - Map of model names (Strings) to model objects (Objects). Model entries may not be null, but the model Map may be null if there is no model data.

          這樣viewName就知道了,返回給DispatcherServerlet,再根據(jù)viewResolver中的定義,就可以知道是/jsp/spring/Product.jsp了。
          也就是說(shuō),viewName也就是jsp文件的名字。

          17,ModelAndView傳遞給頁(yè)面之后頁(yè)面如何使用其中的數(shù)據(jù) ?
           Controller傳遞的model是一個(gè)map,一共傳遞了兩個(gè)key-value對(duì)。
           model.put("itemList", itemList);
           model.put("product", product);
           ok,看jsp頁(yè)面。<c:out value="${product.name}"/>
          <c:forEach var="item" items="${itemList.pageList}">
            <tr bgcolor="#FFFF88">
            <td><b>
            <a href="<c:url value="/shop/viewItem.do"><c:param name="itemId" value="${item.itemId}"/></c:url>">
              <c:out value="${item.itemId}"/>
            </a></b></td>
            <td><c:out value="${item.productId}"/></td>
            <td>
              <c:out value="${item.attribute1}"/>
              <c:out value="${item.attribute2}"/>
              <c:out value="${item.attribute3}"/>
              <c:out value="${item.attribute4}"/>
              <c:out value="${item.attribute5}"/>
              <c:out value="${product.name}"/>
            </td>
            <td><fmt:formatNumber value="${item.listPrice}" pattern="$#,##0.00"/></td>
            <td><a href="<c:url value="/shop/addItemToCart.do"><c:param name="workingItemId" value="${item.itemId}"/></c:url>">
              <img border="0" src="../images/button_add_to_cart.gif"/>
            </a></td>
            </tr>
          </c:forEach>
          原來(lái)是把key當(dāng)作attributename放到了request范圍內(nèi)了。這樣就ok了,model的key實(shí)際上就是request的屬性名字啊。
           model的value就是request的屬性值。jstl真正發(fā)揮簡(jiǎn)潔的威力了。

          18,viewProduct.do里還有一個(gè)翻頁(yè)的邏輯,沒(méi)看明白怎么回事。


          19,viewProduct.do之后再點(diǎn)鏈接就進(jìn)入了viewItem.do,相對(duì)簡(jiǎn)單。不用看了。
          PagedListHolder itemList = new PagedListHolder(this.petStore.getItemListByProduct(productId));
          java.lang.Object
            org.springframework.beans.support.PagedListHolder
          PagedListHolder is a simple state holder for handling lists of objects, separating them into pages. Page numbering starts with 0.
          Constructor Summary
          PagedListHolder()
                    Create a new holder instance.
          PagedListHolder(List source)
                    Create a new holder instance with the given source list, starting with a default sort definition (with "toggleAscendingOnProperty" activated).
          PagedListHolder(List source, SortDefinition sort)
                    Create a new holder instance with the given source list.
           boolean isFirstPage()
                    Return if the current page is the first one.
           boolean isLastPage()
                    Return if the current page is the last one.
           void nextPage()
                    Switch to next page.
           void previousPage()
                    Switch to previous page.
           可以排序。可以設(shè)置頁(yè)數(shù)。
          這 個(gè)類明顯是把所有的結(jié)果一次性查詢出來(lái)后,設(shè)定每頁(yè)個(gè)數(shù),之后再把當(dāng)頁(yè)數(shù)據(jù)發(fā)送給頁(yè)面。雖然不是把全部數(shù)據(jù)發(fā)送給頁(yè)面由頁(yè)面來(lái)分頁(yè),但是一次把全部數(shù)據(jù)都 查詢出來(lái)的做法只適合少量數(shù)據(jù)。如果多量數(shù)據(jù)幾萬(wàn)條的話同時(shí)查出來(lái),存放到session,用不了多久服務(wù)器的內(nèi)存就被耗光了。
          還不太清楚放到session中的對(duì)象什么時(shí)候被晴空,好像只有在退出的時(shí)候才晴空一次。

          20,addItemToCart.do?workingItemId=EST-11,代碼很清楚。有兩點(diǎn)主意:
           一,webUtil org.springframework.web.util.webUtil提供了有限的幾個(gè)方法。
           二,return new ModelAndView("Cart", "cart", cart); // Cart.jsp , key ,value
           因?yàn)椴皇煜batis所以O(shè)RM層的代碼都沒(méi)有閱讀,也就是PetsoreImpl實(shí)現(xiàn)類的各個(gè)DAO實(shí)例都沒(méi)有閱讀。

              removeItemFromCart.do?workingItemId=EST-11 也是同一頁(yè)面上的購(gòu)物車操作 ,過(guò)于簡(jiǎn)單。略
           updateCartQuantities.do //更新的是內(nèi)存中的數(shù)據(jù),所以沒(méi)有什么技術(shù)。

          21,checkout.do有一點(diǎn)需要注意,別的Controller沒(méi)有傳入viewName。它傳了,
           <bean name="/shop/checkout.do" class="org.springframework.samples.jpetstore.web.spring.ViewCartController">
            <property name="successView" value="Checkout"/>
           </bean>
           Controller中:
           private String successView;

           public void setSuccessView(String successView) {
            this.successView = successView;
           }
           最后return new ModelAndView(this.successView, "cart", cart);



          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=571067


          posted on 2007-06-18 17:53 chenguo 閱讀(196) 評(píng)論(0)  編輯  收藏 所屬分類: Spring Dev

          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          留言簿

          隨筆分類(1)

          文章分類(52)

          好友 小山的博客

          最新隨筆

          最新評(píng)論

          主站蜘蛛池模板: 皋兰县| 万山特区| 临高县| 阜康市| 东莞市| 延庆县| 高密市| 武隆县| 西吉县| 巨野县| 长寿区| 马龙县| 贵德县| 万源市| 武陟县| 西畴县| 云安县| 章丘市| 杭锦后旗| 武隆县| 松江区| 巴里| 若羌县| 清新县| 桦南县| 革吉县| 河南省| 巴里| 新民市| 上犹县| 花莲市| 清流县| 清远市| 黔南| 本溪市| 泰来县| 福州市| 肇庆市| 共和县| 蒙自县| 独山县|