Spring是?個開源框架, 他讓我們的開發更加簡單. 他?持?泛的應?場
景, 有著活躍?龐?的社區, 這也是Spring能夠?久不衰的原因.
但是這個概念相對來說, 還是?較抽象.
??句更具體的話來概括Spring, 那就是: Spring 是包含了眾多?具?法的 IoC 容器
容器是?來容納某種物品的(基本)裝置。
?活中的?杯, 垃圾桶, 冰箱等等這些都是容器.
之前接觸的容器
List/Map -> 數據存儲容器
Tomcat -> Web 容器
什么是 IoC
IoC 是Spring的核?思想, 也是常?的?試題, 那什么是IoC呢?
其實IoC我們在前?已經使?了, 我們在前?講到, 在類上?添加 @RestController 和 @Controller 注解, 就是把這個對象交給Spring管理, Spring 框架啟動時就會加載該類. 把對象交 給Spring管理, 就是IoC思想.
IoC: Inversion of Control (控制反轉), 也就是說 Spring 是?個"控制反轉"的容器.
什么是控制反轉呢? 也就是控制權反轉. 什么的控制權發?了反轉? 獲得依賴對象的過程被反轉了
也就是說, 當需要某個對象時, 傳統開發模式中需要??通過 new 創建對象, 現在不需要再進?創 建, 把創建對象的任務交給容器, 程序中只需要依賴注? (Dependency Injection,DI)就可以了.
這個容器稱為:IoC容器. Spring是?個IoC容器, 所以有時Spring 也稱為Spring 容器.
控制反轉是?種思想, 在?活中也是處處體現.
?如?動駕駛, 傳統駕駛?式, ?輛的橫向和縱向駕駛控制權由駕駛員來控制, 現在交給了駕駛?
動化系統來控制, 這也是控制反轉思想在?活中的實現.
?如招聘, 企業的員?招聘,?職, 解雇等控制權, 由?板轉交給給HR(??資源)來處理
IoC 優勢
在傳統的代碼中對象創建順序是:Car -> Framework -> Bottom -> Tire
改進之后解耦的代碼的對象創建順序是:Tire -> Bottom -> Framework -> Car
我們發現了?個規律,通?程序的實現代碼,類的創建順序是反的,傳統代碼是 Car 控制并創建了Framework,Framework 創建并創建了 Bottom,依次往下,?改進之后的控制權發?的反轉,不再是使??對象創建并控制依賴對象了,?是把依賴對象注?將當前對象中,依賴對象的控制權不再由當前類控制了.
這樣的話, 即使依賴類發?任何改變,當前類都是不受影響的,這就是典型的控制反轉,也就是 IoC 的實現思想。學到這?, 我們?概就知道了什么是控制反轉了, 那什么是控制反轉容器呢, 也就是IoC容器

這部分代碼, 就是IoC容器做的?作.
從上?也可以看出來, IoC容器具備以下優點:
資源不由使?資源的雙?管理,?由不使?資源的第三?管理,這可以帶來很多好處。第?,資源集中管理,實現資源的可配置和易管理。第?,降低了使?資源雙?的依賴程度,也就是我們說的耦合度。
資源集中管理: IoC容器會幫我們管理?些資源(對象等), 我們需要使?時, 只需要從IoC容器中去取 就可以了
在創建實例的時候不需要了解其中的細節, 降低了使?資源雙?的依賴程度, 也就是耦合度.
Spring 就是?種IoC容器, 幫助我們來做了這些資源管理.
?DI 介紹
學習了IoC, 什么是DI呢?
DI: Dependency Injection(依賴注?)
容器在運?期間, 動態的為應?程序提供運?時所依賴的資源,稱之為依賴注?。
程序運?時需要某個資源,此時容器就為其提供這個資源.從這點來看, 依賴注?(DI)和控制反轉(IoC)是從不同的?度的描述的同?件事情,依賴注?是
從應?程序的?度來描述, 就是指通過引? IoC 容器,利?依賴關系注?的?式,實現對象之間的解耦.
上述代碼中, 是通過構造函數的?式, 把依賴對象注?到需要使?的對象中的
IoC 是?種思想,也是"?標", ?思想只是?種指導原則,最終還是要有可?的落地?案,? DI 就屬于具體的實現。所以也可以說, DI 是IoC的?種實現.
?如說我今天?情?較好,吃?頓好的犒勞犒勞??,那么"吃?頓好的"是思想和?標(是
IoC),但最后我是吃海底撈還是楊國福?這就是具體的實現,就是 DI。
也就是將資源交給spring管理,是ioc,是要用來使用的,那么具體怎么使用就是di。
Bean的存儲
在之前的??案例中,要把某個對象交給IOC容器管理,需要在類上添加?個注解: @Component
?Spring框架為了更好的服務web應?程序, 提供了更豐富的注解.
共有兩類注解類型可以實現:
類注解:@Controller、@Service、@Repository、@Component、@Configuration.
?法注解:@Bean.
接下來我們分別來看
其實這些能夠將對象交給spring保管的都是component的衍生注解,實現這個功能的就是有component。
從Spring容器中獲取對象
ApplicationContext 翻譯過來就是: Spring 上下?
因為對象都交給 Spring 管理了,所以獲取對象要從 Spring 中獲取,那么就得先得到 Spring 的上下?
關于上下?的概念
上學時, 閱讀理解經常會這樣問: 根據上下?, 說?下你對XX的理解
在計算機領域, 上下?這個概念, 咱們最早是在學習線程時了解到過, ?如我們應?進?線程切換的時候,切換前都會把線程的狀態信息暫時儲存起來,這?的上下?就包括了當前線程的信息,等下次該線程?得到CPU時間的時候, 從上下?中拿到線程上次運?的信息
這個上下?, 就是指當前的運?環境, 也可以看作是?個容器, 容器?存了很多內容, 這些內容是當前運?的環境

獲取bean對象的其他?式
上述代碼是根據類型來查找對象, 如果Spring容器中, 同?個類型存在多個bean的話, 怎么來獲取呢?ApplicationContext 也提供了其他獲取bean的?式, ApplicationContext 獲取bean對象的功能, 是?類BeanFactory提供的功能.

常?的是上述1,2,4種, 這三種?式,獲取到的bean是同一個
其中1,2種都涉及到根據名稱來獲取對象. bean的名稱是什么呢?
Spring bean是Spring框架在運?時管理的對象, Spring會給管理的對象起?個名字.
?如學校管理學?, 會給每個學?分配?個學號, 根據學號, 就可以找到對應的學?.
Spring也是如此, 給每個對象起?個名字, 根據Bean的名稱(BeanId)就可以獲取到對應的對象
Bean 命名約定
默認的命名時將類型改成小駝峰,首字母變成小寫,如果前面兩個字母都是大寫的話,那么默認的命名就是類名,也可以通過自定義來對存儲的變量命名,就是對componen及其衍生注解添加屬性值,這個屬性值就是自定義對象名
序開發?員不需要為bean指定名稱(BeanId), 如果沒有顯式的提供名稱(BeanId),Spring容器將為該bean?成唯?的名稱.
命名約定使?Java標準約定作為實例字段名. 也就是說,bean名稱以?寫字?開頭,然后使?駝峰式??寫.

也有?些特殊情況, 當有多個字符并且第?個和第?個字符都是?寫時, 將保留原始的??寫. 這些規則與java.beans.Introspector.decapitalize (Spring在這?使?的)定義的規則相同.



地址?樣, 說明對象是?個
獲取bean對象, 是?類BeanFactory提供的功能
ApplicationContext VS BeanFactory(常??試題)
繼承關系和功能??來說:Spring 容器有兩個頂級的接?:BeanFactory 和 ApplicationContext。其中 BeanFactory 提供了基礎的訪問容器的能?,?ApplicationContext 屬于 BeanFactory 的?類,它除了繼承了 BeanFactory 的所有功能之外,它還擁有獨特的特性,還添加了對國際化?持、資源訪問?持、以及事件傳播等??的?持.
從性能??來說:ApplicationContext 是?次性加載并初始化所有的 Bean 對象,?
BeanFactory 是需要那個才去加載那個,因此更加輕量. (空間換時間)
為什么這么多類注解?
這個是和應用分層相互對應的,讓程序員看到類注解之后,就能直接了解當前類的?途.
@Controller:控制層, 接收請求, 對請求進?處理, 并進?響應.
@Servie:業務邏輯層, 處理具體的業務邏輯.
@Repository:數據訪問層,也稱為持久層. 負責數據訪問操作
@Configuration:配置層. 處理項?中的?些配置信息
和每個省/市都有??的?牌號是?樣的.
?牌號都是唯?的, 標識?個?輛的. 但是為什么還需要設置不同的?牌開頭呢.?如陜西的?牌號就是:陜X:XXXXXX,北京的?牌號:京X:XXXXXX,甚??個省不同的縣區也
是不同的,?如西安就是,陜A:XXXXX,咸陽:陜B:XXXXXX,寶雞,陜C:XXXXXX,?樣.
這樣做的好處除了可以節約號碼之外,更重要的作?是可以直觀的標識?輛?的歸屬地
序的應?分層,調?流程如下:
其實這些注解??都有?個注解 @Component ,說明它們本?就是屬于 @Component 的"?類".
@Component 是?個元注解,也就是說可以注解其他類注解,如 @Controller , @Service ,
@Repository 等. 這些注解被稱為 @Component 的衍?注解.
@Controller , @Service 和 @Repository ?于更具體的?例(分別在控制層, 業務邏輯層, 持久化層), 在開發過程中, 如果你要在業務邏輯層使? @Component 或@Service,顯然@Service是更好的選擇
?如杯?有喝?杯, 刷?杯等, 但是我們更傾向于在?常喝?時使??杯, 洗漱時使?刷?杯.
更多資料參考: https://docs.spring.io/spring-framework/reference/core/beans/classpathscanning.html#beans-stereotype-annotations
方法注解 @Bean?
注解是添加到某個類上的, 但是存在兩個問題:
使?外部包?的類, 沒辦法添加類注解
?個類, 需要多個對象, ?如多個數據源
這種場景, 我們就需要使??法注解 @Bean
使用bean注解,注解的方法要滿足返回值是需要被spring管理的一個對象,一般都使用public來修飾該方法。
方法注解要配合類注解使用,如果沒有類注解,使用了方法注解也是沒辦法被檢索到的。?
在 Spring 框架的設計中,?法注解 @Bean 要配合類注解才能將對象正常的存儲到 Spring 容器中

定義多個對象
對于同?個類, 如何定義多個對象呢?
?如多數據源的場景, 類是同?個, 但是配置不同, 指向不同的數據源.

定義了多個對象,但是如果單純只靠類名來獲取的話會報錯,因為定義了多個對象,無法確定到底哪個才是真正要使用的。那么就可以通過名稱或者名稱和類來獲取對象。
重命名 Bean
bean注解和component這些注解所交給spring管理的對象默認名是方法名,方法名是全局唯一的,就算不是同一類也不能重復。


當bean注解的方法需要參數時,會自動從spring所管理的對象中取出對應的參數。
如果該參數為基本類型或者包裝類時則不會,而是需要直接對其賦值,可以通過依賴注入,也可以直接聲明默認值
但如果所需參數的類被spring管理不止一個,就會報錯,那么就需要注解@qualifier來確定依賴注入的參數,或者通過一些配置文件可以直接通過參數名來匹配
@Bean
public ExampleBean(@Qualifier("primaryDs") DataSource dataSource) {
? ? // 明確注入ID為"primaryDs"的DataSource
}
依賴注入?
依賴注?是?個過程,是指IoC容器在創建Bean時, 去提供運?時所依賴的資源,?資源指的就是對象.
在上?程序案例中,我們使?了 @Autowired 這個注解,完成了依賴注?的操作.
簡單來說, 就是把對象取出來放到某個類的屬性中.
在?些?章中, 依賴注?也被稱之為 "對象注?", "屬性裝配", 具體含義需要結合?章的上下?來理解
關于依賴注?, Spring也給我們提供了三種?式:
屬性注?(Field Injection)
構造?法注?(Constructor Injection)
Setter 注?(Setter Injection)
屬性注?
屬性注?是使? @Autowired 實現的,將 Service 類注?到 Controller 類中.


構造方法注入
構造?法注?是在類的構造?法中實現注?,如下代碼所?

Setter 注入
Setter 注?和屬性的 Setter ?法實現類似,只不過在設置 set ?法的時候需要加上 @Autowired 注
解 ,如下代碼所?:

三種注入優缺點分析
屬性注?
優點: 簡潔,使??便;
缺點:
只能?于 IoC 容器,如果是? IoC 容器不可?,并且只有在使?的時候才會出現 NPE(空指
針異常)
不能注??個Final修飾的屬性
構造函數注?(Spring 4.X推薦)
優點:
可以注?final修飾的屬性
注?的對象不會被修改
依賴對象在使?前?定會被完全初始化,因為依賴是在類的構造?法中執?的,?構造?法
是在類加載階段就會執?的?法.
通?性好, 構造?法是JDK?持的, 所以更換任何框架,他都是適?的
缺點:
注?多個對象時, 代碼會?較繁瑣?
Setter注?(Spring 3.X推薦)
優點: ?便在類實例之后, 重新對該對象進?配置或者注?
缺點:
不能注??個Final修飾的屬性
注?對象可能會被改變, 因為setter?法可能會被多次調?, 就有被修改的?險
?@Autowired存在的問題




@Autowired 是spring框架提供的注解,?@Resource是JDK提供的注解
@Autowired 默認是按照類型注?,?@Resource是按照名稱注?. 相?于 @Autowired 來說,
@Resource ?持更多的參數設置,例如 name 設置,根據名稱獲取 Bean.
Autowired裝配順序
總結?
Spring, Spring Boot 和Spring MVC的關系以及區別
Spring: 簡單來說, Spring 是?個開發應?框架,什么樣的框架呢,有這么?個標簽:輕量級、?
站式、模塊化,其?的是?于簡化企業級應?程序開發.
Spring的主要功能: 管理對象,以及對象之間的依賴關系, ?向切?編程, 數據庫事務管理, 數據訪問, web框架?持等.
但是Spring具備?度可開放性, 并不強制依賴Spring, 開發者可以?由選擇Spring的部分或者全部, Spring可以?縫繼承第三?框架, ?如數據訪問框架(Hibernate 、JPA), web框架(如Struts、JSF)
Spring MVC: Spring MVC是Spring的?個?框架, Spring誕?之后, ?家覺得很好?, 于是按照MVC
模式設計了?個 MVC框架(?些?Spring 解耦的組件), 主要?于開發WEB應?和?絡接?,所以,
Spring MVC 是?個Web框架.
Spring MVC基于Spring進?開發的, 天?的與Spring框架集成. 可以讓我們更簡潔的進?Web層開發, ?持靈活的 URL 到??控制器的映射, 提供了強?的約定?于配置的契約式編程?持, ?常容易與其他視圖框架集成,如 Velocity、FreeMarker等
Spring Boot: Spring Boot是對Spring的?個封裝,
為了簡化Spring應?的開發?出現的,中?型企業,沒有成本研究??的框架, 使?Spring Boot 可以更加快速的搭建框架, 降級開發成本, 讓開發?員更加專注于Spring應?的開發,??需過多關注XML的配置和?些底層的實現.
Spring Boot 是個腳?架, 插拔式搭建項?, 可以快速的集成其他框架進來.?如想使?SpringBoot開發Web項?, 只需要引?Spring MVC框架即可, Web開發的?作是
SpringMVC完成的, ?不是SpringBoot, 想完成數據訪問, 只需要引?Mybatis框架即可.
Spring Boot只是輔助簡化項?開發的, 讓開發變得更加簡單, 甚?不需要額外的web服務器, 直接?成jar包執?即可.
最后?句話總結: Spring MVC和Spring Boot都屬于Spring,Spring MVC 是基于Spring的?個
MVC 框架,?Spring Boot 是基于Spring的?套快速開發整合包.
?如圖書系統代碼中
整體框架是通過SpringBoot搭建的
IoC, DI功能是Spring的提供的
web相關功能是Spring MVC提供的