Spring全面詳解(學習總結)
Spring FrameWork
一、 前言
二、IOC(控制反轉)
??? 2.1 對于IOC的理解
??? 2.2如何使用IOC
??? 2.3配置文件的解讀
??? 2.4IOC容器創(chuàng)建bean的兩種方式
??? 2.5從IOC容器中取bean
??? 2.6bean的屬性如果包含特殊字符
三、DI(依賴注入)
四、Spring中的bean
五、Spring中的繼承
六、Spring的依賴
七、Spring讀取外部資源
八、Spring的p命名空間
九、Spring工廠方法
??? 9.1靜態(tài)工廠方法
??? 9.2實例工廠方法
十、Spring IOC 自動裝配 autowire
??? 10.1自動裝配
??? 10.2 Spring IOC基于注解的開發(fā)
??? 10.3實際開發(fā)中的使用
十一、Spring AOP
這篇內容把Spring的基本知識點都講到了,篇幅比較長,大家可以用于復習,也可以在學習相關知識點的時候,來看看對應內容。對于一些難點,IOC,AOP等,我通過流程圖,代碼,文字結合來進行講解,可以更好的理解

Spring FrameWork
一、 前言
Spring是當前Java開發(fā)的行業(yè)標準,第一框架
Spring FrameWork已經從最初取代EJB的框架逐步發(fā)展成一套完整的生態(tài),最新的版本是5.x
Spring架構體系圖

Spring兩大核心機制:
IOC:工廠模式
AOP:代理模式
二、IOC(控制反轉)
2.1 對于IOC的理解
傳統(tǒng)開發(fā)中,需要調用對象的時候,需要調用者手動來創(chuàng)建被調用者的實例,即對象是由調用者new出來的
但是在Spring框架中,創(chuàng)建對象的工作不再由調用者來完成,而是交給IOC容器來創(chuàng)建,再推送給調用者,整個流程完成反轉,所以是控制反轉

就比如說假設買東西,以前我們需要自己去超市買東西,但是現(xiàn)在我們可以不用自己去超市,我們只要把購物袋放在家門口,IOC就會自己去把我們想要的東西買回來,然后放在袋子里面,我們打開袋子拿起來用就可以了
IOC的特點是解耦合。
比如說A需要用到B,傳統(tǒng)的開發(fā),我們要直接創(chuàng)建B的實例,但是在Spring中,IOC這個容器會創(chuàng)建B的實例,然后把這個B注入到A

2.2如何使用IOC
創(chuàng)建maven工程,在pom.xml中導入相關依賴
創(chuàng)建實體類Student
在resources路徑下創(chuàng)建applicationContext.xml配置文件
傳統(tǒng)的開發(fā)方式:手動new Student
IOC容器通過讀取配置文件,加載配置
bean
標簽來創(chuàng)建對象就像買菜一樣,我們不需要自己親自買,但是要寫一張單子,告訴說要買什么,程序也是類似的,我們要告訴Spring框架要創(chuàng)建哪些對象,怎樣創(chuàng)建對象

調用API,從IOC獲取對象

2.3配置文件的解讀
通過配置
bean
標簽來完成對象的管理id
:對象名class
:對象的模板類(所有交給IOC容器來管理的類必須要有無參構造函數(shù),因為Spring底層是通過反射機制來創(chuàng)建對象,調用的是無參構造)對象的成員變量通過
property
標簽完成賦值name
:成員變量名value
:成員變量值(基本數(shù)據(jù)類型,String可以直接賦值,如果是其他引用類型不可以通過value賦值)ref
:把IOC中的另一個bean賦給當前成員變量(DI)

2.4IOC容器創(chuàng)建bean的兩種方式
無參構造函數(shù)(需要提供對應的set方法)

有參構造函數(shù)
2.5從IOC容器中取bean
通過id取值
通過類型取值
當IOC容器中存在兩個以上Student Bean的時候就會拋出異常,因為此時沒有唯一的bean


2.6bean的屬性如果包含特殊字符

三、DI(依賴注入)
DI:指bean之間的依賴注入,設置對象之間的級聯(lián)關系
Classes
Student
applicationContext-di.xml

bean之間的級聯(lián)需要使用ref屬性,而不能用value屬性,否則會拋出類型轉換異常



如果把學生裝到班級里面,又把班級裝到學生里面,就導致無限遞歸循環(huán)裝配,最終棧溢出
四、Spring中的bean
bean是根據(jù)scope來生成的,表示bean的作用域,scope有4種類型
singleton,單例,表示通過Spring容器獲取的對象是唯一的,是默認值



prototype,原型,表示通過Spring容器獲取的對象是不同的
配置文件


request,請求,表示在異常HTTP請求內有效
session,會話,表示在一個用戶會話內有效
request和session一般用于web項目
singleton模式下,只要加載IOC容器,不管是否從IOC種取出bean,配置文件中的bean都會被創(chuàng)建,而且只會創(chuàng)建一個對象
prototype模式下,如果不從IOC中取出bean,則不創(chuàng)建對象,取一次bean,就會創(chuàng)建一個對象
五、Spring中的繼承
Spring中的繼承不同于Java中的繼承
Java中的繼承是針對于類的
Spring中的繼承是針對于對象(bean)

通過設置bean標簽的parent屬性建立繼承關系,同時子bean可以覆蓋父bean的屬性值
Spring的繼承是針對對象的,所以子bean和父bean并不需要同一個數(shù)據(jù)類型,只要其成員變量列表一致即可
六、Spring的依賴
用來設置兩個bean的創(chuàng)建順序
IOC容器默認情況下是通過applicationContext.xml中bean的配置順序來決定創(chuàng)建順序的,配置在前面的bean會先被創(chuàng)建
在不更改applicationContext.xml配置順序的前提下,通過設置bean之間的依賴關系來調整bean的創(chuàng)建順序

七、Spring讀取外部資源
在實際開發(fā)中,數(shù)據(jù)庫的配置會一般會單獨保存到后綴為properties的文件,方便維護和修改
如果用Spring來加載數(shù)據(jù)源,就需要在applicationContext.xml中讀取properties中的數(shù)據(jù),這就是讀取外部資源
jdbc.properties
spring-properties.xml


八、Spring的p命名空間
用來簡化xml配置

九、Spring工廠方法
IOC通過工廠模式創(chuàng)建bean有兩種方式:
靜態(tài)工廠方法
實例工廠方法
靜態(tài)工廠類不需要實例化,實例工廠類需要實例化
9.1靜態(tài)工廠方法
創(chuàng)建Car類
2.創(chuàng)建靜態(tài)工廠類,靜態(tài)工廠方法
3.spring-factory.xml
factory-method 指向靜態(tài)方法
constructor-arg的value屬性是調用靜態(tài)方法傳入的參數(shù)
9.2實例工廠方法
創(chuàng)建實例工廠類,工廠方法
2.spring.xml
區(qū)別:

靜態(tài)工廠方法創(chuàng)建Car對象,不需要實例化工廠對象,因為靜態(tài)工廠的靜態(tài)方法,不需要創(chuàng)建對象就可以調用了
實例工廠方法創(chuàng)建Car對象,需要實例化工廠對象,因為getCar方法是非靜態(tài)的,就必須通過實例化對象才能調用,所以 必須創(chuàng)建工廠對象,spring.xml需要配置兩個bean,一個是工廠bean,一個是Car Bean
spring.xml中 class+factory-method的形式是直接調用類中的工廠方法
spring.xml中factory-bean+factory-method的形式是調用工廠bean中的工廠方法,就必須先創(chuàng)建工廠bean
十、Spring IOC 自動裝配 autowire
10.1自動裝配
自動裝載是Spring提供的一種更加簡便的方式來完成DI,不需要手動配置property,IOC 容器會自動選擇bean來完成注入
自動裝載有兩種方式:
byName:通過屬性名完成自動裝載
byType:通過屬性對應的數(shù)據(jù)類型完成自動裝載
byName的操作如下:
創(chuàng)建Person實體類
2.在spring.xml中配置Car和Person對應的bean,并且通過自動裝載完成依賴注入

注:如果bean的id有多個一致的,會報錯,如Bean name 'car' is already used in this <beans> element
byType的操作如下:

使用byType進行自動裝配的時候,必須保證IOC中有且只有一個符合,如果有多個符合,則報下面的異常:

10.2 Spring IOC基于注解的開發(fā)
Spring IOC的作用是幫助開發(fā)者創(chuàng)建項目中所需要的bean,同時完成bean之間的依賴注入關系,DI
實現(xiàn)該功能有兩種方式:
基于XML配置
基于注解
基于注解有兩步操作,缺一不可:
配置自動掃包
添加注解
DI
注解默認的beanid是類名以小寫開頭,我們可以通過value來設置
如果我們想要把datasource也注入進來需要怎么做呢?
首先我們要把DataSource先掃進來



@Autowired默認是通過byType進行裝配,如果要改為byName,需要配合@Qualifier注解來完成
這表明把IOC中id為datasource的bean注入到repository中
實體類中普通的成員變量(String,包裝類等),可以通過@Value注解來賦值
10.3實際開發(fā)中的使用
實際開發(fā)中我們會把程序分成三層:
Controller
Service
Repository(DAO)
關系Controller—>Service---->Repository

@Component注解是把標注的類加載到IOC容器中,實際開發(fā)中可以根據(jù)業(yè)務需求分別使用@Controller,@Service,@Repository注解來標注控制層類,業(yè)務層類,持久層類
十一、Spring AOP
AOP (Aspect Oriented Programming) 面向切面編程
OOP (Object Oriented Programming) 面向對象編程,用對象化的思想來完成程序
AOP是對OOP的一個補充,是在另外一個維度上抽象出對象
具體指程序運行時動態(tài)地把非業(yè)務代碼切入到業(yè)務代碼中,從而實現(xiàn)程序的解耦合,把非業(yè)務代碼抽象成一個對象,對對象編程就是面向切面編程

上面這種形式的代碼維護性很差,代碼復用性差

AOP的優(yōu)點:可以降低模塊之間的耦合性
提供代碼的復用性
提高代碼的維護性
集中管理非業(yè)務代碼,便于維護
業(yè)務代碼不受非業(yè)務代碼影響,邏輯更加清晰
通過一個例子來理解AOP。
創(chuàng)建一個計算器接口Cal
2.創(chuàng)建接口的實現(xiàn)類
日志打印
在每個方法開始位置輸出參數(shù)信息
在每個方法結束位置輸出結果信息
對于計算器來說,加減乘除就是業(yè)務代碼,日志打印就是非業(yè)務代碼
AOP如何實現(xiàn)? 使用動態(tài)代理的方式來實現(xiàn)
代理首先要具備CalImpl的所有功能(實現(xiàn)同一個接口),并且在這個基礎上,擴展出打印日志的功能
刪除CalImpl方法中國所有打印日志的代碼,只保留業(yè)務代碼
創(chuàng)建MyInvocationHandler類(不是動態(tài)代理類),實現(xiàn)InvocationHandler接口,生成動態(tài)代理類 。動態(tài)代理類需要動態(tài)生成,需要獲取到委托類的接口信息,根據(jù)這些接口信息動態(tài)生成一個代理類,然后再由ClassLoader用來把動態(tài)生成的類加載到JVM


代理類需要有和委托類一樣的功能,所以委托類和代理類需要實現(xiàn)同樣的接口,因此,我們要獲取到委托類的接口信息,根據(jù)這個接口信息就可以生成一個類,再通過ClassLoader加載到內存里面

上述代碼通過動態(tài)代理機制實現(xiàn)了業(yè)務代碼和非業(yè)務代碼的解耦合,這是Spring AOP的底層實現(xiàn)機制,真正使用 Spring AOP進行開發(fā)的時候,不需要這么復雜
Spring AOP的開發(fā)步驟
創(chuàng)建切面類 Loggerspect
@Component,把切面類加載到IOC容器中
@Aspect,表示該類是一個切面類
@Before,表示方法的執(zhí)行時機是在業(yè)務方法之前,execution表達式表示切入點是CalImpl中的所有方法
@After,表示方法的執(zhí)行時機是在業(yè)務方法結束以后,execution表達式表示切入點是CalImpl類中的方法
@AfterReturning,表示方法的執(zhí)行時機是在業(yè)務方法返回結果后,execution表達式表示切入點是CalImpl類中的方法,returning是把業(yè)務方法的返回值和切面類方法的形參進行綁定
@AfterThrowing,表示方法的執(zhí)行時機是在業(yè)務方法拋出異常后,execution表達式表示切入點是CalImpl類中的方法,throwing是把業(yè)務方法的異常和切面類方法的形參進行綁定

2.委托類也需要添加@Component
3.spring-aop.xml
aspectj-autoproxy ,Spring IOC容器會結合切面對象和委托對象自動生成動態(tài)代理對象,AOP底層就是通過動態(tài)代理機制來實現(xiàn)的
4.測試

AOP的概念
切面對象:根據(jù)切面抽象出來的對象,CalImpl所有方法中需要加入日志的部分LoggerAspect
通知:切面對象具體執(zhí)行的代碼,即非業(yè)務代碼,LoggerAspect對象打印日志的代碼
目標:被橫切的對象,即CalImpl,把通知加入其中
代理:切面對象,通知,目標混合后的結果,即我們通過JDK動態(tài)代理機制創(chuàng)建的對象
連接點:需要被橫切的位置,即通知要插入業(yè)務代碼的具體位置

最后
??? 小伙伴們學習編程,有時候不知道怎么學,從哪里開始學。掌握了基本的一些語法或者做了兩個案例后,不知道下一步怎么走,不知道如何去學習更加高深的知識。
那么對于這些小伙伴們,我準備了大量的視頻教程,PDF電子書籍,以及源代碼!
只要+up主威信wangkeit1備注“B站”就可以白嫖領取啦!?
