Spring 學習筆記(一)Spring核心容器

前言

一年多前,我開始了Java Web學習之旅。這個旅程是斷斷續續的,由於它與個人工做領域沒有太多重合。最近看了不少Java和Spring的資料,然而離感受本身學會了,仍有一點距離。所以,就繼續以前的Servlet和JSP博客系列吧。html

本系列將會覆蓋到Spring的基礎以及Spring MVC, 固然還有Spring Boot. 除了開始介紹 Spring及其配置的文章,後面將都使用 Spring Boot。spring

同時,本系列將不是照本宣科的學習,還會有一些思考和討論。不然,很容易陷入一堆配置的泥潭,越學越糊塗。作好準備,咱們開始吧!數據庫

Spring簡介

本段內容引自這裏, 很棒的博客!編程

Spring框架由Rod Johnson開發,初版於2004年發佈。Spring是一個從實際開發中抽取出來的框架,所以它完成了大量開發中的通用步驟,留給開發者的僅僅是與特定應用相關的部分,從而大大提升了企業應用的開發效率。設計模式

Spring總結起來優勢以下:安全

  • 低侵入式設計,代碼的污染極低。
  • 獨立於各類應用服務器,基於Spring框架的應用,能夠真正實現Write Once,Run Anywhere的承諾。
  • Spring的IoC容器下降了業務對象替換的複雜性,提升了組件之間的解耦。
  • Spring的AOP支持容許將一些通用任務如安全、事務、日誌等進行集中式管理,從而提供了更好的複用。
  • Spring的ORM和DAO提供了與第三方持久層框架的良好整合,並簡化了底層的數據庫訪問。
  • Spring的高度開放性,並不強制應用徹底依賴於Spring,開發者可自由選用Spring框架的部分或所有。
  • 蓬勃的社區,Spring全家桶,你懂的。

spring

依賴注入

Spring的歷史很少談,但提到Spring,必定會提到它的核心容器。你可能還聽過另外一個詞:IoC,控制反轉。這個詞顯然更加不知所云。
IoC是更早提出的概念,它是OO設計模式的一種。而在IoC以前,還有個設計原則,叫依賴倒置原則(DIP)。服務器

依賴倒置原則:高層模塊不該該依賴低層模塊,而兩個都應該依賴抽象。抽象不該該依賴於細節,細節應該依賴於抽象。

關於它們的前世此生,這篇文章講的很是好。session

總結起來就是:框架

  • DIP強調要面向接口編程,所以使用者最好只持有被使用者的接口的引用。
  • IoC進一步指出建立所依賴的對象這個動做也不該該由使用者負責,那就要交給第三方處理。
  • DI (依賴注入)是IoC的一種實現。常見方式是構造函數注入屬性注入
  • IoC 容器是功能更增強大的依賴注入框架,能夠實現經過配置文件配置依賴,以及對象的生命週期管理等等。

使用容器是必須的嗎?

顯然,對於Java Web來講,使用Spring容器別無選擇。以致於會讓一些人認爲這是天經地義的。然而放眼其餘語言,幾乎都有各自的容器框架,卻不多有像Spring這樣獲得了廣泛的應用。甚至,在咱們公司的.NET開發規範中,明確指出了Unity這種容器框架太重,不推薦使用。如下是一些討論(在討論以前,咱們先明確一點 —— IoC 不等於 IoC容器):函數

  • 「使用容器能夠方便單元測試」。並非,只要面向接口編程,多提供幾個構造函數,就能夠很方便的使用Mock作單元測試。
  • 「建立依賴對象有時過於複雜,交給容器便可」。建立對象能夠交給工廠模式解決。
  • "容器能夠集中配置,並且只修改XML,不編譯就能夠切換應用策略"。額,這些功能使用工廠+配置文件+反射也能夠作。何況,使用XML配置依賴真的好嗎?那爲何Spring 4.0以後改成推薦使用代碼配置呢?
  • 「使用容器能夠方便地管理對象生命週期,方便實現單例模式」。 額,算是一個小理由。
  • "使用容器能夠方便實現AOP,不然很難實現一個動態代理"。這算是一個比較好的理由。

而使用容器的缺點也顯而易見,現在處處都是Annotation,根本不是集中配置。須要記住的約定一大堆,出了問題還要排查是否是Spring注入的錯。在代碼中定位依賴也一樣很不直觀。

如下是網上的一些討論,並不是爲了撕,只是提供更全面的認識。
知乎
水木社區

最後,既來之則安之,下面咱們正式開始。

Bean與容器

JavaBean、EJB、POJO這些東西又有不少歷史能夠扯。具體參見這裏。結論就是,在Spring容器裏,Bean就是POJO。也就是說:

  • Spring容器是一個超級大工廠(和倉庫),負責建立、管理全部的Java對象,這些Java對象被稱爲Bean。
  • Spring容器管理容器中Bean之間的依賴關係,Spring使用"依賴注入"來管理Bean之間的依賴關係。

Spring容器的入口

Spring經過應用上下文(Application Context)來行使容器的工做。Spring自帶了多種類型的應用上下文實現,每種都以具體的類表示。下面是經常使用的幾個:

  • AnnotationConfigApplicationContext :從Java配置類中加載Spring應用上下文。
  • AnnotationConfigWebApplicationContext :從Java配置類中加載Spring Web應用上下文。
  • ClassPathXmlApplicationContext :從ClassPath下的XML配置文件中加載Spring應用上下文。
  • FileSystemXmlApplicationContext :從文件系統的XML配置文件中加載Spring應用上下文。
  • XmlWebApplicationContext :從Web應用中的XML配置文件中加載Spring Web應用上下文。

既然是入口類,使用它們只有一種方式:直接或間接地new出一個實例。以下是一個簡單的例子:

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User u = (User)context.getBean("user");
System.out.println(u);

Spring配置的三種方案

Spring的配置方案隨着歷史的演進,支持如下三種:

  • 在XML中顯式配置
  • 隱式的bean自動掃描和自動裝配
  • 在Java中顯式配置

XML配置是最老的技術;使用Java類配置是最新的推薦。而自動掃描和自動裝配使用XML和Java均可以指定。

使用Java顯式配置

  • 使用@Configuration註解建立配置類。
  • 使用@Bean註解聲明Bean。

隱式的bean自動掃描和自動裝配

所謂裝配(wiring)就是指建立所依賴的對象的行爲,即依賴注入。自動裝配就是容器推斷出所依賴的具體對象,建立它並設置好使用類。
組件掃描則是指Spring能夠掃描應用中有特殊註解的類,爲其建立Bean。

  • 經過@Component註解標記可被發現的類。當介紹到Spring Web部分時,咱們還會看到其餘幾個類似的註解。
  • 經過@ComponentScan註解啓用組件掃描。
  • 經過@Autowired註解開啓自動裝配。另外Spring也重用了JDK中的@Resource註解。二者有微小的差別。

使用XML顯式配置

使用Java Config能作到的在XML中也能作到。例如:

  • <bean class="xxx"/>聲明bean。
  • <context:component-scan base-package="yyy"/> 啓用組件掃描。
  • <bean autowire="true"/>開啓自動裝配。

Bean的做用域

當經過Spring容器建立一個Bean實例時,不只能夠完成Bean實例的實例化,還能夠爲Bean指定特定的做用域。Spring支持以下五種做用域:

  1. Singleton: 單例模式,在整個Spring容器中,singleton做用域的Bean將只生成一個實例。
  2. Prototype: 每次經過容器的getBean()方法獲取prototype做用域的Bean時,都將產生一個新的Bean實例。
  3. Request: 對於一次HTTP請求,request做用域的Bean將只生成一個實例,這意味着,在同一次HTTP請求內,程序每次請求該Bean,獲得的老是同一個實例。只有在Web應用中使用Spring時,該做用域才真正有效。
  4. Session: 對於一次HTTP會話,session做用域的Bean將只生成一個實例,這意味着,在同一次HTTP會話內,程序每次請求該Bean,獲得的老是同一個實例。只有在Web應用中使用Spring時,該做用域才真正有效。
  5. Global session: 每一個全局的HTTP Session對應一個Bean實例。在典型的狀況下,僅在使用portlet context的時候有效,一樣只在Web應用中有效。

若是不指定Bean的做用域,Spring默認使用Singleton做用域。Prototype做用域的Bean的建立、銷燬代價比較大。而Singleton做用域的Bean實例一旦建立成功,就能夠重複使用。所以,應該儘可能避免將Bean設置成Prototype做用域。

相關文章
相關標籤/搜索