国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Spring中的持久性

2019-11-18 16:12:57
字體:
供稿:網(wǎng)友

  編者按:簡單而有技巧地解決問題總是比蠻力解決要好。這就是最近出版的Better, Faster, Lighter java一書中所遵循的原則。從這本書的第八章中節(jié)選出來的這個關(guān)于SPRing的兩部分的系列文章,也體現(xiàn)了書的作者BrUCe Tate和Justin Gehtland所信奉的這個原則。本周Bruce和Justin將繼續(xù)第一部分,向Pet Store示例添加持久性,并探討Spring框架中的持久性邏輯方面。

添加持久性
  CartItem對象不一定非要是持久的。另一方面,您希望從數(shù)據(jù)庫中獲取產(chǎn)品和類別。J2EE應(yīng)用程序開發(fā)人員一直在尋求一種成熟的持久性方法而沒有成功。好的持久性框架應(yīng)該支持透明,并且不侵入域模型。Spring允許您將透明對象與數(shù)據(jù)訪問層分離開來。然后Spring使您可以很容易地在持久性之上建層。可以使用JDBC抽象層,它可以分離掉JDBC中許多冗長乏味、易于出錯的方面,比如連接管理和錯誤處理。Spring JDBC層使用一個稱為回調(diào)模板 的特性來將控制權(quán)由應(yīng)用程序交給Spring框架。借助于該策略,Spring不再需要管理連接、結(jié)果集和特定于RDBMS的錯誤。當(dāng)想要使用JDBC直接處理關(guān)系查詢時,該框架就非常有用了。

  通常,我們都寧愿處理對象而不愿處理關(guān)系。Spring也有一個用于透明持久性的模型。jPetStore使用Spring的OR映射層,該層提供了許多預(yù)包裝的選項。現(xiàn)在Spring支持針對基本JDBC DAO、Hibernate和JDO的映射層。這個例子使用一個稱為iBATIS SQL Maps的DAO框架來實現(xiàn)Spring DAO層。

模型
  每個Spring解決方案都從一個透明域模型開始。例8-3從透明模型對象(一個產(chǎn)品)開始。

  例8-3. Product.java

public class Product implements Serializable {  private String productId;  private String categoryId;  private String name;  private String description;  public String getProductId( ) { return productId; }  public void setProductId(String productId) { this.productId = productId.trim( ); }  public String getCategoryId( ) { return categoryId; }  public void setCategoryId(String categoryId) { this.categoryId = categoryId; }  public String getName( ) { return name; }  public void setName(String name) { this.name = name; }  public String getDescription( ) { return description; }  public void setDescription(String description) { this.description = description; }  public String toString( ) {    return getName( );  }}

  這里沒什么特別的。它完全由屬性組成,通過getter、setter以及一個實用方法toString進(jìn)行訪問。如果您看一下jPetStore應(yīng)用程序,就會發(fā)現(xiàn)域中其他每個持久性對象都有類似的類:Account、Order、Category、Item和LineItem。

映射
  至于Hibernate,iBATIS SQL Maps框架有一個映射文件。在該文件中,Java bean中的每個持久性屬性都映射到一個數(shù)據(jù)庫列。使用SQL Maps,可以在該映射文件中創(chuàng)建所有的SQL,將所有的SQL與xml映射文件隔離開來。例8-4顯示了Product的XML映射支持。

  例8-4. Product.xml

[1]  [2]       [3]                                   [4]          select PRODUCTID, NAME, DESCN, CATEGORY from PRODUCT where PRODUCTID = #value#     [5]          select PRODUCTID, NAME, DESCN, CATEGORY from PRODUCT where CATEGORY = #value#     [6]          select PRODUCTID, NAME, DESCN, CATEGORY from PRODUCT                             lower(name) like #keyWordList[]# OR lower(category) like #keywordList[]# OR lower(descn) like #keywordList[]#                          


  下面是注釋的含義:

  [1]每個映射文件對應(yīng)于一個域?qū)ο蟆1纠械挠驅(qū)ο箨P(guān)系到為該DAO所指定的查詢的返回類型。

  [2]關(guān)于DAO層的其他信息,比如緩存策略,也屬于映射文件。這里,iBatis將緩存維持24小時,然后刷新。

  [3]當(dāng)然了,每個查詢都返回一個產(chǎn)品。該映射將結(jié)果集中的每一列與產(chǎn)品中的一個字段聯(lián)系起來。

  [4]該SQL語句找出給定productID的產(chǎn)品。

  [5]該SQL語句找出一個類別中的所有產(chǎn)品。它返回一個產(chǎn)品列表。

  [6]該SQL語句是動態(tài)的。IBatis迭代關(guān)鍵字列表,形成一個動態(tài)查詢。

  到目前為止,您已經(jīng)看到了Product及其映射的域模型,包括查詢。您已經(jīng)上路了。

DAO接口
  應(yīng)用程序必須與Spring和SQL Maps都進(jìn)行集成。應(yīng)用程序通過一個DAO接口和一個具體實現(xiàn)將二者聯(lián)系起來。例8-5就是該接口。

  例8-5. ProductDAO.java

public interface ProductDao {  List getProductListByCategory(String categoryId) throws DataaccessException;  List searchProductList(String keywords) throws DataAccessException;  Product getProduct(String productId) throws DataAccessException;}

  這非常簡單??梢钥吹剑x在映射中的每個查詢都有一個接口。具體來說,getProduct接口通過ID查找產(chǎn)品,getProductListByCategory接口返回一個類別中的所有產(chǎn)品,還有一個基于關(guān)鍵字的動態(tài)查詢接口?,F(xiàn)在,DAO拋出Spring異常,任何使用DAO的邏輯都有一致的異常,即使您之后決定更改實現(xiàn)。

DAO實現(xiàn)
  余下的就是要使用SQL Map來實現(xiàn)接口。例8-6是Product的SQL Map實現(xiàn)。

  例8-6. SqlMapProductDao.java

    public class SqlMapProductDao extends SqlMapDaoSupport implements ProductDao {[1]  public List getProductListByCategory(String categoryId) throws DataAccessException {       return getSqlMapTemplate( ).executeQueryForList("getProductListByCategory",      }[1]  public Product getProduct(String productId) throws DataAccessException {       return (Product) getSqlMapTemplate( ).executeQueryForObject("getProduct", productId);     }[1]  public List searchProductList(String keywords) throws DataAccessException {       Object parameterObject = new ProductSearch(keywords);       return getSqlMapTemplate( ).executeQueryForList("searchProductList", parameterObject);     }     /* Inner Classes */[2]  public static class ProductSearch {        private List keywordList = new ArrayList( );        public ProductSearch(String keywords) {          StringTokenizer splitter = new StringTokenizer(keywords, " ", false);          while (splitter.hasMoreTokens( )) {            this.keywordList.add("%" + splitter.nextToken( ) + "%");          }        }        public List getKeywordList( ) {          return keywordList;        }     }    }

  下面是注釋的含義:

  [1]這些方法提供了接口的SQL Map實現(xiàn)。其他的實現(xiàn)可能使用Hibernate、JDO或straight JDBC。在本例中,getTemplate調(diào)用指示Spring獲取支持iBATIS SQL Map的模板,并使用該框架執(zhí)行適當(dāng)?shù)牟樵儭?/P>

  [2]我并非特別喜歡內(nèi)部類,但是這是通常實現(xiàn)關(guān)鍵字查詢的方法。在本例中,內(nèi)部類通過實現(xiàn)getKeywordList來支持searchProductList方法。使用余下的DAO實現(xiàn),內(nèi)部類有助于組織代碼基址,將所有的支持都保存在一個地方。

  現(xiàn)在我們看到了映射、模型和DAO。有了一個完全持久性的模型。接下來,我們要使用代碼訪問DAO層。jPetStore通過一個外觀層來接受所有的DAO訪問。

通過外觀使用模型
  正如第3章一樣,通常對模型使用一個高級接口非常有用,它稱為外觀。在本例中,jPetStore外觀有三個作用:
  • 合并數(shù)據(jù)訪問層所有的客戶端;
  • 為其他的應(yīng)用程序提供一個公共用戶界面;
  • 用作與其他服務(wù)(比如事務(wù)支持)的連接點。


  在本例中,外觀是一個非常薄的層,它環(huán)繞所有的DAO。通過配置和方法攔截器,Spring使外觀具有聲明式事務(wù)支持。在本例中,外觀存在于兩個部分中:接口和實現(xiàn)。接口允許不影響其他代碼地更改外觀的實現(xiàn)。例8-7顯示了接口。

  例8-7. PetStoreFacade.java

public interface PetStoreFacade {  Account getAccount(String username);  Account getAccount(String username, String password);  void insertAccount(Account account);  void updateAccount(Account account);  List getUsernameList( );  List getCategoryList( );  Category getCategory(String categoryId);  List getProductListByCategory(String categoryId);  List searchProductList(String keywords);  Product getProduct(String productId);  List getItemListByProduct(String productId);  Item getItem(String itemId);  boolean isItemInStock(String itemId);  void insertOrder(Order order);  Order getOrder(int orderId);  List getOrdersByUsername(String username);}

  可以將該接口視為所有創(chuàng)建、讀、更新或刪除任何Pet Store對象的方法的統(tǒng)一列表。注意,您不能看到來自所有DAO的方法,而只能看到我們希望公開給外界的方法。還要注意接口中的命名一致性。這很重要,因為,在我們的配置文件中,您可以看到用來傳播以get、search、update或insert開頭的方法的事務(wù)支持。

  實現(xiàn)調(diào)用底層的DAO來執(zhí)行適當(dāng)?shù)牟僮?。必須在接口中實現(xiàn)所有的方法。例8-8是與ProductDAO相關(guān)的方法的實現(xiàn)。

  例8-8. Excerpt fromPetStoreImpl.java

[1] private ProductDao productDao;  ...    public void setProductDao(ProductDao productDao) {       this.productDao = productDao;	}  ...[2] public List getProductListByCategory(String categoryId) {       return this.productDao.getProductListByCategory(categoryId);    }	    public List searchProductList(String keywords) {       return this.productDao.searchProductList(keywords);    }  ...

  下面是注釋的含義:

  [1]顯示DAO訪問(包括粗體文本)。Spring框架使用反射將DAO插入到外觀中。這意味著外觀必須支持一個set方法和一個私有成員變量。

  [2]提供數(shù)據(jù)訪問的方法使用底層的DAO來做實際工作(包括對粗體文本的處理)。

  當(dāng)然了,我沒有給出接口的所有方法的實現(xiàn)。只顯示了與產(chǎn)品相關(guān)的方法。它們分為兩部分。

  首先,應(yīng)用程序上下文將每個DAO連接到外觀。Spring使用反射和bean工廠來創(chuàng)建產(chǎn)品DAO,并使用setProductDAO API來對其進(jìn)行設(shè)置。為此,外觀需要一個變量來保存DAO以及一個set方法來通過反射訪問它。

  其次,實現(xiàn)非常簡單。外觀只將請求傳遞給下面的模型層。但是,最終的實現(xiàn)要強大得多。外觀用作一個支持聲明式事務(wù)的EJB會話bean。通過配置,POJO變成了一個聲明式事務(wù)協(xié)調(diào)程序!它也是整個數(shù)據(jù)庫層的中心控制點。余下的工作就是配置DAO層了。

配置DAO層
  剛才我們只看到了模型的配置。例8-9則顯示了一個使用簡單事務(wù)管理的數(shù)據(jù)庫的數(shù)據(jù)層配置。正如您所預(yù)料的,您將看到JDBC驅(qū)動程序的配置和所有DAO bean的聲明。

  例8-9. dataAccessContext-local.xml

   [1]        /WEB-INF/jdbc.properties    [2]                                 [3]            [4]               classpath:/sql-map-config.xml    [5]        	   		 		   	   		 		   	   		 		   	   		 		   	   	       			   	   	   


  下面是注釋的含義:

  [1]這個bean處理JDBC配置。JDBC配置屬性在一個標(biāo)準(zhǔn)的JDBC配置文件中,這使得它們的維護(hù)和讀取更為容易。Spring提供了一個配置類,使得用戶可以輕松地讀取屬性文件,而無需將其轉(zhuǎn)換為XML。

  [2]這里是數(shù)據(jù)源。它是一個標(biāo)準(zhǔn)的J2EE數(shù)據(jù)源。許多J2EE應(yīng)用程序或框架都將應(yīng)用程序或框架硬連接到一個給定的數(shù)據(jù)源上。而對其進(jìn)行配置,就可以輕松地選擇自己的數(shù)據(jù)源(以及池化策略)了。

  [3]applicationContext.xml配置設(shè)置事務(wù)策略。該配置指定實現(xiàn)。該應(yīng)用程序使用數(shù)據(jù)源事務(wù)管理器,它通過JDBC將事務(wù)管理委托給數(shù)據(jù)庫(使用提交和回滾)。

  [4]必須對構(gòu)建DAO的iBATIS SQL Map實用工具進(jìn)行配置。這里配置了。

  [5]最后,我們看到了實際的DAO配置。不知道您是否記得,applicationContext.xml文件通過名稱引用每個bean。

  配置不止從模型或視圖中解除了持久性層的耦合。還從持久性層解除事務(wù)管理的耦合,將事務(wù)策略與實現(xiàn)分離開來,并隔離數(shù)據(jù)源。下面我們來看除了配置之外的眾多好處。

優(yōu)點
  這就是Product的所有持久性代碼。JPetStore其余的代碼也都類似于此。應(yīng)用程序有效地將整個域模型隔離到單獨的一個層中。域?qū)θ魏畏?wù)都沒有依賴性,包括數(shù)據(jù)層。我們還將所有的數(shù)據(jù)訪問都封裝到一個整潔的DAO層中,該層獨立于數(shù)據(jù)存儲。要注意您沒有看到的:

數(shù)據(jù)源配置
  由Spring框架處理。您不必管理一整套單元素集合(針對會話管理)、數(shù)據(jù)源等等。您還可以將重要決定(如:數(shù)據(jù)源類型)延遲到部署時。

連接處理
  Spring框架管理所有的連接處理。一個最常見的JDBC錯誤就是連接泄漏。如果不對連接的關(guān)閉非常小心,特別是在異常條件中,應(yīng)用程序就很容易失去穩(wěn)定而崩潰。

特化的異常
  許多框架將SQL異常傳至頂層。它們通常都將可能特化到您自己的RDBMS中的代碼內(nèi)置,這使得難以編碼可移植的應(yīng)用程序。Spring有它自己的異常層次結(jié)構(gòu),從而使您遠(yuǎn)離這些問題。此外,如果換為使用Hibernate或JDO方法,不需要對異常處理做任何更改。

  到現(xiàn)在為止,我們有了一個整潔、透明的域模型和一個獨立于數(shù)據(jù)庫的、不怎么需要維護(hù)的服務(wù)層。每個層都巧妙地封裝起來了??赐炅撕笈_邏輯,現(xiàn)在我們來為應(yīng)用程序添加一個用戶界面。

呈現(xiàn)
  大多數(shù)情況下,Spring框架并不重新改造現(xiàn)行的技術(shù)。但是,在呈現(xiàn)邏輯方面,Spring引入了一個稱為MVC Web的簡單的模型-視圖-控制器框架,它包括許多競爭性的架構(gòu),比如Struts和Java Server Faces (JSF)。使用Spring不一定非得使用MVC Web。但是如果決定使用它,就會得到一些好處:
  • MVC Web不指定視圖選擇。其他框架可能會對您所喜歡的視圖技術(shù)提供更好的支持,比如Velocity(專有的)和Struts (jsp)。例如,Struts通過請求屬性公開模型。因此,要使用諸如Velocity之類不理解Servlet API的技術(shù),就需要構(gòu)建一個橋梁servlet。Spring則是通過一種通用的映射來公開模型,所以它可以與任何視圖技術(shù)一起使用。
  • MVC Web提供Spring應(yīng)用程序的所有方面的一致配置。它使用與其他框架相同的反向控制范例。
  • MVC Web使測試變得更輕松。因為無需再擴(kuò)展一個類(比如Struts中的Action或ActionForm),所以可以很容易地模擬請求和響應(yīng)。

  如果曾經(jīng)使用過Struts,您就應(yīng)該很熟悉MVC Web的基本范例。圖8-4顯示了它的工作機制??刂破骰旧咸幚砹怂袕妮斎胍晥D傳入的請求。如果輸入請求是一個提交的表單,控制器就調(diào)用一個(由程序員創(chuàng)建和配置的)業(yè)務(wù)驗證例程,并根據(jù)結(jié)果向用戶發(fā)送相關(guān)的錯誤視圖或者成功視圖。

Spring中的持久性(圖一)
圖8-4. MVC Web框架的工作機制類似于Struts

配置
  就像對Spring框架的其他元素一樣,要了解一個新的應(yīng)用程序,要從配置文件開始深入研究。在本例中,用戶界面是在petstore-servlet.xml文件中進(jìn)行配置的。

  考慮搜索一個類別中的產(chǎn)品的Html頁面,以及根據(jù)關(guān)鍵字搜索產(chǎn)品的HTML頁面。配置文件需要兩個應(yīng)用程序上下文文件的控制器。每個記錄項指定一個控制器以及模型對象,如例8-10所示。

  例8-10. web.xml節(jié)選

                  


  還記得吧,所有對數(shù)據(jù)層的訪問都是通過外觀進(jìn)行的。是的,這些bean ID記錄項指定了外觀,稱為petstore。應(yīng)用程序中的每個表單都以同樣的方式工作。我們進(jìn)一步來看看searchProducts的控制器。

控制器
  對于MVC Web,每個表單共享一個控制器實例,它發(fā)送所有與給定表單相關(guān)的請求。它還將表單封送到正確的驗證邏輯,并向用戶返回適當(dāng)?shù)囊晥D。例8-11顯示了searchProducts視圖的控制器。

  例8-11. SearchProductsController.java

   public class SearchProductsController implements Controller {[1] private PetStoreFacade petStore;    public void setPetStore(PetStoreFacade petStore) {       this.petStore = petStore;    }[2] public ModelAndView handleRequest(HttpServletRequest request,                                      HttpServletResponse response)       throws Exception {[3]    if (request.getParameter("search") != null) {          String keyword = request.getParameter("keyword");          if (keyword == null  keyword.length( ) == 0) {             return new ModelAndView("Error",                                  "message",       "Please enter a keyword to search for, then press the search button.");          }          else {[4]          PagedListHolder productList = new PagedListHolder(                     this.petStore.searchProductList(keyword.toLowerCase( )));             productList.setPageSize(4);             request.getsession( ).setAttribute(                     "SearchProductsController_productList", productList);[5]          return new ModelAndView("SearchProducts", "productList", productList);          }       }       else {[6]       String page = request.getParameter("page");            PagedListHolder productList = (PagedListHolder) request.getSession( ).              getAttribute("SearchProductsController_productList");          if ("next".equals(page)) {             productList.nextPage( );          }          else if ("previous".equals(page)) {             productList.previousPage( );          }          return new ModelAndView("SearchProducts", "productList", productList);       }      }	     }

  下面是注釋的含義:

  [1]每個控制器都有對適當(dāng)?shù)挠蚰P偷目刂茩?quán)。在本例中,視圖自然是通過外觀來訪問模型的。

  [2]控制器有一個類似于servlet但是實際上不是servlet的接口。因此用戶請求通過一個調(diào)度servlet傳入,該servlet將請求發(fā)送給適當(dāng)?shù)目刂破?,填充request成員??刂破髦豁憫?yīng)適當(dāng)?shù)恼埱?,調(diào)用業(yè)務(wù)數(shù)據(jù),并將控制權(quán)發(fā)送給適當(dāng)?shù)捻撁妗?/P>

  [3]在本例中,請求是“search”。控制器必須分析出適當(dāng)?shù)年P(guān)鍵字。

  [4]控制器使用用戶所提供的關(guān)鍵字調(diào)用業(yè)務(wù)邏輯。

  [5]控制器將適當(dāng)?shù)囊晥D(以及適當(dāng)?shù)哪P停┌l(fā)送給用戶。

  [6]在本例中,請求是“page”。我們的用戶界面支持適用于同一個頁面的多種產(chǎn)品。

表單
  像Struts一樣,Spring可以將HTML表單映射為Java對象。例8-12是當(dāng)一個Pet Store用戶注冊一個帳號時所返回的Java bean。

  例8-12. AccountForm.java

public class AccountForm {  private Account account;  private boolean newAccount;  private String repeatedPassword;  public AccountForm(Account account) {    this.account = account;    this.newAccount = false;  }  public AccountForm( ) {    this.account = new Account( );    this.newAccount = true;  }  public Account getAccount( ) {    return account;  }  public boolean isNewAccount( ) {    return newAccount;  }  public void setRepeatedPassword(String repeatedPassword) {    this.repeatedPassword = repeatedPassword;  }  public String getRepeatedPassword( ) {    return repeatedPassword;  }}


  這些bean的每個字段都直接對應(yīng)于一個HTML輸入字段或控制權(quán)。Spring框架將一個提交請求轉(zhuǎn)換為表單,然后可以將它當(dāng)作POJO來訪問以進(jìn)行驗證、映射輸入數(shù)據(jù)或用于其他用途。與Struts不同的是,Spring表單對象可以是任何Java bean。沒有必要擴(kuò)展ActionForm。這非常重要,因為你不必從一個ActionForm復(fù)制屬性到域?qū)ο蠡蛑祵ο蟆?/P>驗證
  您可能已經(jīng)注意到了原始applciationContext.xml中的驗證邏輯。這些bean通常都被視為業(yè)務(wù)邏輯,但是它們與用戶界面關(guān)系密切,而且它們是由Spring框架直接調(diào)用的。當(dāng)用戶提交表單后,Spring就激活驗證邏輯。Spring根據(jù)結(jié)果向適當(dāng)?shù)捻撁姘l(fā)送控制權(quán)。例8-13顯示了驗證帳號表單的AccountValidator類。

  例8-13. AccountValidator.java

public class AccountValidator implements Validator {   public boolean supports(Class clazz) {      return Account.class.isAssignableFrom(clazz);   }   public void validate(Object obj, Errors errors) {      ValidationUtils.rejectIfEmpty(errors, "firstName", "FIRST_NAME_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "lastName", "LAST_NAME_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "email", "EMAIL_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "phone", "PHONE_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "address1", "ADDRESS_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "city", "CITY_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "state", "STATE_REQUIRED",       ValidationUtils.rejectIfEmpty(errors, "zip", "ZIP_REQUIRED", "ZIP is required.");      ValidationUtils.rejectIfEmpty(errors, "country", "COUNTRY_REQUIRED",    }}

  在本例中,Spring框架從幾個方面使開發(fā)人員的生活變得更為輕松。開發(fā)人員不需要手動編寫驗證方法。有許多預(yù)包裝的方法??蚣茇?fù)責(zé)驗證和發(fā)送??蚣茇?fù)責(zé)根據(jù)成功或失敗的結(jié)果發(fā)送控制權(quán)。

  僅僅一章還不足以判斷Spring框架,但是您已經(jīng)看到了它的整體要點。該框架——更重要的是,這種編碼方式——的優(yōu)點應(yīng)該顯而易見了。特別要注意整潔的分層架構(gòu)所提供的清晰性和簡單性。您可以預(yù)料到,將業(yè)務(wù)邏輯與一個類似于Spring的透明框架相結(jié)合是多么輕松的事情。

小結(jié)
  我選擇jPetStore應(yīng)用程序是有很多原因的。最主要的原因是,可以很快就看到一個簡單、快速、輕量級的應(yīng)用程序與其他可選方案之間的區(qū)別。如果您還不是Spring的信徒,我建議您看一看Pet Store的EJB版本。如果您還沒有看過,您會為二者的差別而感到震驚。Spring版本是透明而獨立的,而EJB則是侵入式的,而且還依賴于容器。Spring版本可讀性非常好,而J2EE版本則被EJB最佳實踐的復(fù)雜性所淹沒。

  我并非一直是Spring的信徒。實際上,在Rod Johnson與我在波士頓的一次會議上被介紹認(rèn)識之前,我根本不知道他是誰。后來我逐漸欣賞起這個簡單、優(yōu)雅而重要的框架。如果您對Spring還很陌生,那么您只能看到一個應(yīng)用程序。我希望通過這個應(yīng)用程序,您能夠領(lǐng)會它如何體現(xiàn)本書中的這些原則:

盡可能地簡單
  Spring的易用性和可讀性。在僅僅一章之中,我們介紹了一個具有事務(wù)、持久性、一個完整的web前端以及一個完全的模塊化配置引擎的應(yīng)用程序。

只做一件事,但是要做好
  Spring的框架有許多不同的方面和子框架。但是,它將每個概念很好地分離開來。Spring最基本的意義在于它的bean工廠和配置服務(wù),它們使得用戶可以管理依賴性而無需耦合代碼。Spring的每個附加層都是完全去耦合并且獨立的。

爭取透明
  Spring應(yīng)用程序完全不需要依賴于基礎(chǔ)容器。實際上,這些應(yīng)用程序可以輕松自如地存在于容器外。用戶只需手動創(chuàng)建和配置它們。這種能力使得Spring應(yīng)用程序成為開發(fā)人員樂于測試的應(yīng)用程序。

內(nèi)容決定形式
  Spring利用它所包含的各種框架為用戶提供了靈活的選擇。針對數(shù)據(jù)源和登錄的Apache項目為它奠定了良好的基礎(chǔ)。Spring提供了多種可配置的選項,使用戶可以針對給定的解決方案選擇最佳的框架。

支持?jǐn)U展
  Spring可能是現(xiàn)存的最為開放和可擴(kuò)展的容器。它允許使用常見的配置服務(wù)和整潔的抽象快速有效地進(jìn)行擴(kuò)展。

  此處對Spring的介紹并不全面。我的目標(biāo)只是向您說明,利用本書前六章所介紹的概念是可以構(gòu)建現(xiàn)實世界的應(yīng)用程序的。如果想了解得更多,一定要研究一下Spring的高級特性:

  • 與Hibernate和JDO的集成
  • 面向方面編程(AOP)的概念
  • 包含JTA支持的事務(wù)模板

  《Better, Faster, Lighter Java》一書的兩位作者將在其他章節(jié)中繼續(xù)探討使用了本書所介紹的基本原則的實際例子。例如,一個稱為Simple Spider的服務(wù)的實現(xiàn),您還將看到該服務(wù)被集成到Spring中。之后您將會看到類似框架的更多優(yōu)點。


  原文出處 Persistence in Spring: http://www.onjava.com/pub/a/onjava/excerpt/BFLJava_chap8/index1.html

Spring中的持久性(圖二)
 作者簡介Bruce A.ate是一名山地車手和皮劃艇手,也是2個孩子的父親。在閑暇時間里,他還是一名獨立顧問。他住在德克薩斯州的首府奧斯汀。他編寫了4本書,其中包括最暢銷的《Bitter Java》一書,最近出版了《Better,Faster,Lighter Java》(O'Reilly)。 Alexander Ananiev是一個程序員、作者、導(dǎo)師和指導(dǎo)員,他專攻現(xiàn)實世界軟件應(yīng)用程序。

(出處:http://www.survivalescaperooms.com)



發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 华蓥市| 即墨市| 绿春县| 陵水| 廉江市| 温宿县| 防城港市| 南阳市| 章丘市| 绩溪县| 金平| 新丰县| 明星| 宝山区| 广宁县| 平乡县| 象州县| 永靖县| 滦南县| 木兰县| 开化县| 紫金县| 公安县| 石首市| 溧水县| 柯坪县| 荆州市| 阳谷县| 绥棱县| 临洮县| 苍南县| 尉犁县| 三河市| 平舆县| 马尔康县| 达日县| 合水县| 盈江县| 江川县| 河池市| 桐梓县|