Spring(一):Spring開篇

筆者前言

作爲一個Java Developer,Spring我相信是大家都繞不開的一個圈子,又或者你剛好是一位想要或即將成爲Java工程師的追夢者,那麼這一塊的東西你更要給予更多的關注和投入。現在的大部分企業在選擇小夥伴的時候不會問你什麼是EJB,見面的第一句可能就是:你對Spring掌握到了什麼程度。我呢,也是根據我近幾年的這開發經驗,會梳理下這方面的相關的知識,一個是方便自己後續的查閱,再一個也是和大家共勉。後續文章中如有疑問或者是錯誤的地方歡迎大傢俬信我,謝謝!

好了,話不多說了我們還是進入正題,開篇我們講Spring,其他相關內容可從我的文章中進行檢索。

Spring 最初誕生(創建者:RodJohnson)的目的是解決企業應用開發的複雜性,使用JavaBean來完成企業應用的開發,幫助企業開發出更簡單、更易於測試和相對松耦合的應用程序。

1、框架有什麼?

在這裏插入圖片描述
最新的框架已經來到了5.x版本了,想要了解框架內更多信息的小夥伴可以上Spring開發者官網(https://spring.io/) 瞭解下。

  • Core Container(核心容器):最基礎的部分。它爲我們提供了整套的基於BeanFactory(工廠模式)創建的JavaBean的管理,依賴注入(DI)、控制反轉(IOC)的使用將配置和實際代碼得以分離。除此之外,容器中還包含有應用的上下文、表達式的支持、以及許多企業組件的支持(需要時進行配置即可)。
  • Aop、Aspects(切面編程):面向切面編程。幫助Spring應用能夠進一步的解耦,可以邏輯處理(通用業務、事務、日誌等)的進一步抽取,提高代碼複用性。
  • Instrmentation:很少使用。給JVM添加添加代理用的,爲Tomcat 傳遞類文件。
  • Message:消息的集成。集成Messaging api以及爲消息協議提供支持
  • Data Access(數據訪問與集成):數據訪問與持久化的支持。無論你是鍾情於JDBC、還是習慣ORM、OXM等這些的數據集成方式他都統統囊括,也提供了完備的事務處理。它不僅可以支持主流的數據訪問框架,還支持我們自定義我們自己的數據訪問的方式,非常人性化。
  • Web:Web組件的支持。很好的和現在主流的MVC組件進行結合,像Structs、JSF、SrpingMvc等等,本身也提供了像遠程調用、REST API的支持等。
  • Test:測試模塊。重要性對於開發者而言不言而喻了。

2、爲什麼使用它?

在看過基本的框架組成後,我們再來看看它能給我們帶來哪些的改變。

  • 輕量。無論是從大小或開銷而言它都是輕量的
  • 非侵入式。應用程序代碼對框架的依賴小。
  • 控制反轉(IOC)。將對象的創建和依賴的查找都交由容器,不但簡化了開發的還降低了組件之間的耦合性。“硬編碼”的減少也使得後期的維護性得以提高
  • 面向切面(AOP)。完成對通用邏輯的統一處理,如:事務、日誌、安全等方面的處理,使得應用本身只要關注業務邏輯的實現,帶來了簡潔的代碼和高的複用性。
  • 良好的數據持久化支持。打通主流的第三方持久化框架,簡化了繁雜的數據訪問代碼。
  • 開放性。開源且非常良好的開放性使得你可以自由搭配自己想要的組件和內容。
  • 良好的測試支持。易於構建單元測試

3、核心內容:

a、管理Bean

這邊我們要知道兩個詞:依賴注入(Dependency Injection)控制反轉(Inverse of Control,IoC)
我想原先我們最常用的建立依賴關係就是通過“硬編碼”來實現,但是隨着程序複雜度的上升,這種的方式帶來的弊端也是非常明顯的。那麼我們來看看Spring這個Bean大工廠他是怎麼做的呢?
首先我們需要爲Bean建立相應的配置信息,然後Spring容器會根據我們提供的這些配置信息主動的幫我們去創建這些對象(由IoC容器來控制對象的創建),創建後它再查找以及注入相應的依賴對象,所以在Spring應用程序中的對象只是被動的接受(或被分配)依賴的對象。
這種由容器控制對象(還可以是文件等)的創建再將對象反向提供給所需的對象的方式就叫做“控制反轉”,IoC其實不是一種什麼技術,它是一種設計的思想或原則,和“好萊塢”法則(Don’t call us,we’ll call you)是一樣的道理:不要打電話給我們,我們會電話你(不主動的去創建對象,IoC容器幫對象找到依賴關係並進行注入)。
DI和IoC其實說的是同一件事,只不過他們是從兩個不同的角度來看待這個過程的。

讓我們通過一些比較實際的說明來對上述兩個名詞做一個更深入的理解吧。

LV1:在我們創建對象的時候原始的做法是:主動通過New的方式來創建對象,然後再調用所創建的對象中的相應的方法。
LV2:使用工廠模式後這個過程就變成了:對象的創建在工廠中進行New的方式進行創建,然後我們主動地通過工廠來獲取對象,然後再調用相應的方法。
LV3:使用IoC的方式:我們只需要聲明我們需要的對象而不用做實例的創建,創建會由容器完成並將對象傳遞給使用者。

Spring常用的注入方式有兩種,分別是:
設值注入:是指容器通過成員變量的setter方法來注入被依賴對象。優點:直觀、簡單(Spring中大量使用)
構造注入:是指通過構造函數進行注入。優點:順序可以自己在構造函數中決定、無需擔心後續代碼破壞、
Ps:若依賴關係不會發生變化應採用構造注入,否則應考慮設值注入。

b、Bean作用域

  • singleton: 單例模式,在整個Spring IoC容器中,singleton作用域的Bean將只生成一個實例;(默認使用)
  • prototype: 每次通過容器的getBean方法獲取prototype作用域的Bean時,都將產生一個新的Bean實例;(Bean的創建、銷燬的對應的開銷都較大)
  • request: 對於一次HTTP請求,request作用域的Bean將只生成一個實例,在同一次HTTP請求內,程序每次請求該Bean,得到的總是同一個實例。只有在Web應用中使用Spring時,該作用域才真正有效
  • session:對於一次HTTP會話,session作用域的Bean將只生成一個實例,這意味着,在同一次HTTP會話內,程序每次請求該Bean,得到的總是同一個實例。只有在Web應用中使用Spring時,該作用域才真正有效;
  • global session: 每個全局的HTTP Session對應一個Bean實例。在典型的情況下,僅在使用portlet context的時候有效,同樣只在Web應用中有效。

c、面向切面

OOP這個作爲程序猿入坑的第一課我們再熟悉不過了,不過它在整個程序設計的過程是縱向的,像繼承、抽象、多態等這些更多的是一個子上而下的關係描繪的是一個應用的程序的層級圖,真正到應用實現的時候你會發現對於一些系統級的服務或者是通用的業務功能,會充斥在我們每一個層級,一定程度上加重了系統的複雜度。
我們來看一個例子更好的理解面向切面的設計:

案例:一棟10層樓的大廈被一個集團所承包,現在每一層都由該集團的一個子公司入住,共十家子公司,那麼就會 變成每一層都會有一個人力部門負責招聘,一個行政部門負責水電,這些部門做着同樣的事情但是出現重複的出現了在各個樓層,現在集團爲了統一管控,建立統一的行政和財務總管各個公司的事務,並取消各個公司相應的部門,各個公司只要關注自己的核心業務即可。這樣的管控就叫做AOP,抽取出各個通用的業務或系統模塊統一進行執行,而各個子公司內部的組織結構分層就叫做OOP了。

上述例子爲個人拙見,不需要理解的可以直接跳過,那麼Spring的AOP長什麼樣呢,我們一起來看下。

Aop的實現上也可以分成兩類:
一、靜態的。AOP框架在編譯階段對程序進行修改,即實現對目標類的增強,生成靜態的AOP代理類。(較好的性能,但需要使用特殊的編譯器)
==》AspectJ爲靜態AOP的代表,是一個較爲主流的AOP框架,提供了強大和豐富的AOP功能,框架內主要幫助我們定義瞭如何表達、定義AOP編程中的語法規範,通過這套語法規範,可以方便地用AOP來解決Java語言中存在的交叉關注點的問題,以及提供編譯、調試工具等。
二、動態的。AOP框架在運行階段動態生成AOP代理,以實現對目標對象的增強,以Spring AOP爲代表。(純Java,無需特殊編譯器,性能較差)

Aop關鍵術語:

  • 通知/增強(Advice):在特定的切入點執行的增強處理。Spring的通知有5種類型:before、after、after-returning、after-throwing和around這五種類型
  • 切面(Aspect): 可以理解爲一個類,在當中多用於定義Advice;
  • 連接點(Joinpoint): 表示在何種操作發生時跳轉到相應的切面。比如方法調用時、修改字段時和拋出異常時等等,在Spring AOP中,連接點總是方法的調用;
  • 切入點(Pointcut): 可以插入增強處理的連接點。簡而言之,當某個連接點滿足指定要求時,該連接點將被添加增強處理,該連接點也就變成了切入點Spring的AOP支持;

Spring中的AOP代理由Spring的IoC容器負責生成、管理,其依賴關係也由IoC容器負責管理。爲了在應用中使用@AspectJ支持,Spring需要添加三個庫:1、aspectjweaver.jar 2、aspectjrt.jar 3、aopalliance.jar

鑑於AOP的以上特性,所以常常通過AOP來處理一些具有橫切性質的系統級服務,如事務管理、安全檢查、緩存、對象池管理等。

d、“自動裝配” 與 “零配置”

Spring 檢查XML配置文件內容,確定依賴關係,爲調用者Bean注入被依賴的Bean。在配置文件中可以通過元素的default-autowire進行指定(配置文件全局指定,全部生效),或是通過元素的autowire進行指定(只對該Bean有效)。

自動裝配的方式:

  • no: 不使用自動裝配(默認)。依賴必須通過ref元素進行顯示的定義。顯示的方式能夠讓我們更加的清晰Bean之間的依賴關係,所以在較大的環境中建議使用
  • byName:通過setter方法名自動裝配。Bean的id與setter方法名去掉set後的名稱一樣時進行注入。若沒找到則不會注入。
  • byType: 通過setter方法的參數類型來自動裝配。Bean類型與setter方法的參數類型一樣時進行注入,若找到多個這樣的Bean,就拋出異常,若沒有找到則不會注入。
  • constructor:與byType類似,這邊是使用構造函數的參數類型。如果容器不能找到一個和構造方法參數類型一樣的Bean,則會拋出一個異常;
  • autodetect:由容器自動決定是使用byType還是使用constructor。

Spring的“零”配置是什麼意思呢,其實就是將繁雜的編寫配置文件工作省略掉,通過配置自動掃描包的地址以及註解來實現所謂的零配置。

首先要在配置文件中指定要自動掃描的包,如:

<context:component-scan base-package="com.missxhh.spring.test"/>

其次就是爲我們的JavaBean指定Bean的類型(配置類型通過註解Annotation的方式來實現),主要包括以下:

@Component:普通的JavaBean組件類
@Controller:控制器組件類
@Service:業務邏輯組件類
@Repository:DAO組件類

在配置完JavaBean後,可以使用@Resource來進行依賴的配置,這個要卸載setter方法或變量的上面

“零配置”下的自動裝配
Spring 很貼心的爲我們提供了@Autowired這個註解(Spring2.5後),用來爲我們的方法或變量指定自動裝配。@Autowired模式在通過byType的方式進行自動裝配的(可以結合@Qualifier進行精確的裝配).

4、ORM與拓展

Spring 對於數據訪問的封裝已經很到位了,spring-jdbc提供了對於傳統SQL的使用,spring-orm又滿足我們對於ORM(對象關係應用)的追求,spring-tx事務處理也可以和上述二者搭配使用。同時Spring也在避免一直地“重複造輪子”,針對數據訪問的處理你也可以完全委託給其它的ORM組件,如Hibernate、Mybaits、Jpa等等,基於此由Spring擴展出的像SSH(Struct2 + Spring + Hibernate)、SSM(Spring + SpringMVC + MyBatis)等框架也是被現在很多的企業所認可和使用的

5、家族成員

由於Spring開源的特性,就會湧現出無數的開發者爲其添磚加瓦,演變成現在原來越完善的這樣的一個生態。那麼都有些什麼東西呢,以下是我目前接觸到的較爲實用的一些框架技術,如果有其他好用框架組件可以聯繫我,大家共同探討。

SSH、SSM這個上面已經有提過了,這邊就不做過多的說明。
Spring Mvc:基於Spring的MVC平臺,不過要再結合其他的JDBC或ORM框架才能使得這個框架完備。
Spring Security:支持系統授權、認證的支持。
Spring Mobile:支持對手機設備檢測等功能。
Spring Boot:現行主流的微服務平臺,後面我也會出專門
Spring Cloud:現行主流的分佈式微服務框架。
JEECG:一款基於SpringMvc+MiniDao的開源框架
…未完待續

The End

好了,關於Spring框架的介紹我就先簡單的介紹在這邊,如果大家有其他需要幫助的地方可以私信(或者關注我們網站獲取我的聯繫方式)與我聯繫,我們共同探討,共同進步。後面我會針對SpringMVC單獨進行講解,如果有需要的可以關注相應的文章。

謝謝閱讀,您的關注就是對我最大的動力!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章