《Spring實戰》第四版讀書筆記 第一章 Spring之旅

1.1 簡化Java開發

爲了下降Java開發的複雜性,Spring採起了如下四種關鍵策略:spring

  • 基於POJO的輕量級和最小侵入性編程;
  • 經過依賴注入和麪向接口實現鬆耦合;
  • 基於切面和慣例進行聲明式編程;
  • 經過切面和模板減小樣板式代碼。

1.1.2 依賴注入

耦合具備兩面性。一方面,緊密耦合的代碼難以測試、難以複用、難以理解,而且典型的表現出「打地鼠」式的bug特性(修復一個bug,將會出現一個或者更多的bug)。另外一方面,必定程度的耦合有時必須的——徹底沒有耦合的代碼什麼也作不了。爲了完成有實際意義的功能,不一樣的類必須以適當的方式進行交互。總而言之,耦合是必須的,但應當被當心謹慎的管理。編程

經過DI,對象的依賴關係將由系統中負責協調各對象的第三方組件在建立對象的時候進行設定。對象無需自行建立或管理它們的依賴關係。依賴關係將被自動注入到須要它們的對象中去。安全

DI帶來的最大收益是鬆耦合。若是一個對象只經過接口(而不是具體實現或初始化過程)來代表依賴關係,那麼這種依賴就可以在對象自己絕不知情的狀況下,用不一樣的具體實現進行替換。框架

Spring經過應用上下文裝載bean的定義並把它們組裝起來。Spring應用上下文全權負責對象的建立和組裝。Spring自帶了多種應用上下文的實現,它們之間主要的區別僅僅在於如何加載配置。模塊化

1.1.3 應用切面

面向切面編程(aspect-oriented programming,AOP)容許你把遍及應用各處的功能分離出來造成可重用的組件。post

系統由許多不一樣的組件組成,每個組件各負責一塊特定功能。除了實現自身核心的功能以外,這些組件還常常承擔者額外的職責。諸如日誌、事務管理和安全這樣的系統服務常常融入到自身具備業務邏輯的組件中去,這些系統服務一般被成爲橫切關注點,應爲它們會跨越系統的多個組件。測試

若是將這些關注點分散到多個組件中去,代碼會帶來雙重的複雜性:日誌

  • 實現系統關注點功能的代碼將會重複出如今多個組件中。這意味這若是要改變這些關注點的邏輯,必須修改各個模塊中的相關實現。即便把這些關注點抽象爲一個獨立的模塊,其餘模塊只是調用它的方法,但方法的調用仍是會重複出如今各個模塊中。對象

  • 組件會由於那些與自身核心業務無關的代碼而變得混亂。一個想地址簿增長地址條目的方法應該只關注若是添加地址,而不該該關注它是否是安全的或者是否須要支持事務。接口

AOP可以使這些服務模塊化,並以聲明的方式將它們應用到它們須要影響的組件中去。所形成的結果就是這些組件會具備更高的內聚性而且會更加關注自身的業務,徹底不須要涉及系統服務的複雜性。總之,AOP可以確保POJO的簡單性。

1.1.4 使用模版消除樣板式代碼

JDBC不是產生樣板式代碼的惟一場景。JMS、JNDI和使用REST服務一般也涉及大量的重複代碼。

1.2 容納Bean

Spring自帶了多個容器實現,能夠概括爲兩種不一樣的類型。bean工廠(由org.springframework.beans.factory.BeanFactory接口定義)是最簡單的容器,提供基本的DI支持。應用上下文(由org.springframework.context.ApplicationContext接口定義)基於BeanFactory構建,並提供應用框架級別的服務,例如從屬性文件解析文本信息以及發佈應用事件給感興趣的事件監聽者。

1.2.1 使用應用上下文

Spring自帶了多種類型的應用上下文,如下一個較經常使用:

  • AnnotationConfigApplicationContext;
  • AnnotationConfigWebApplicationContext;
  • ClassPathXmlApplicationContext;
  • FileSystemXmlApplicationContext;
  • XmlWebApplicationContext。

FileSystemXmlApplicationContext和ClassPathXmlApplicationContext的區別在於:FileSystemXmlApplicationContext在指定文件系統路徑下查找,而ClassPathXmlApplicationContext在全部的類路徑(包括JAR文件)下查找。

若是想從Java配置中加載應用上下文,可使用AnnotationConfigApplicationContext。

1.2.2 bean的生命週期

  1. Spring對bean進行實例化;
  2. Spring將值和bean的引用注入到bean對應的屬性中;
  3. 若是bean實現了BeanNameAware接口,Spring將bean的ID傳遞給setBeanName()方法;
  4. 若是bean實現了BeanFactoryAware接口,Spring將調用setBeanFactory()方法,將BeanFactory實例傳入;
  5. 若是bean實現了ApplicationContextAware接口,Spring將調用setApplicationContext()方法,將bean所在的應用上下文的引用傳入進來;
  6. 若是bean實現了BeanPostProcessor接口,Spring將調用它的postProcessBeforeInitialization()方法;
  7. 若是bean實現了InitializingBean接口,Spring將調用它的afterPropertiesSet()方法。相似的,若是bean使用init-method聲明瞭初始化方法或使用了@PostConstruct註解,該方法也會被調用;
  8. 若是bean實現了BeanPostProcessor接口,Spring將調用postProcessAfterInitialization()方法;
  9. 此時,bean已經準備就緒,能夠被應用程序使用了,它們將一直駐留在應用上下文中,直到應用上下文被銷燬;
  10. 若是bean實現了DisposableBean接口,Spring將調用它的destroy()接口方法。一樣,若是bean使用destroy-method聲明瞭銷燬方法或使用@PreDestory,該方法也會被調用。
相關文章
相關標籤/搜索