Spring的簡介安裝及配置

Mr_TXQ發表於2020-10-16

Spring

Spring簡介
Spring框架是一種輕量級的、一站式的企業級開發解決方案
框架(framework):是一組設計思想、規範、API的精心組合,專門用來解決某一層次或領域的問題
輕量級(lightweight):此處是相對於EJB框架來說的,在資源佔用、開發部署維護、學習成本等方面Spring都比
EJB輕便。
一站式(full-stack):即一步到位,Spring本身提供了豐富的功能特性,又直接整合了一批優秀框架,對於那些
沒有直接整合的其他框架,也提供了一層簡單的封裝讓開發人員可以方便的手動整合,即Spring可以滿足專案各個
層次的要求。
整個Spring有三個核心模組:Spring容器、Spring AOP、宣告式事務管理。
Spring框架有眾多模組,各個模組相互獨立又能很好的合作

spring模組

就我們現階段的學習目標來說,上面這張圖太過複雜,可簡化如下:

spring模組

Spring容器
Spring容器是Spring的核心之一,用來存放、管理bean,也稱為bean容器
bean:被Spring容器管理的Java物件稱為bean,比如service類的物件、dao類的物件等。整個專案的執行是由各
種bean支撐起來的,每個bean都是構成專案的一個元件。
Spring容器對bean的管理包括:建立、注入依賴、初始化、銷燬等。開發人員通過配置的方式指定Spring如何管
理bean。

配置方式有兩種:XML檔案和註解

為什麼要把物件交給Spring容器管理呢?

1 Spring必須把物件統一管理起來,才能實現其他功能特性,也就是說Spring提供的其他功能特性絕大部分都依賴
Spring容器
2 開發人員不用自己編碼管理這些物件,可以專注於實現業務邏輯
3 使物件的使用和建立相分離,方便修改和擴充套件

Spring核心配置檔案
Spring可在XML配置檔案中定義bean、管理bean,配置檔案的根元素是<beans>,檔名任意,課程中命名為
beans.xml,另外也經常使用applicationContext.xml等名稱。
Spring模組眾多,可配置大量內容,Spring提供了多個schema檔案分類描述這些內容,平時使用時,可以把常用的
schema都引入配置檔案中。

bean定義
可以使用<bean>標籤配置、管理bean
id屬性指定bean的id,使用時可以通過id找到該bean
name屬性指定bean的名稱,和id作用一樣
class屬性指定這個bean所表示的Java類的物件
一個<bean>標籤就是一個bean定義,需要注意的是bean的本質是Java物件,而bean定義的本質是配置資訊,但有
些時候我們說bean,也可能表示bean定義,可根據具體語境進行區分,或者不用區分。
這種使用class屬性指定bean型別的配置方式,Spring在建立bean時會直接使用類的建構函式建立。

容器物件:ApplicationContext
ApplicationContext是Spring的上下文物件,代表整個Spring框架,基本上也就代表了整個應用程式,它同時也
是Spring容器物件,所有的bean都儲存在這個物件中。
ApplicationContext有多種建立方式,普通Java專案中可以使用ClassPathXmlApplicationContext建立,建立
時需要指定beans.xml在類路徑下的位置。
Spring容器在建立的時候,會先讀取所有的bean定義並儲存起來,然後建立出bean,預設以單例的方式管理bean
getBean()用來在Spring容器中查詢並返回bean,可以根據id或name查詢,也可以根據型別查詢。如果找不到會
丟擲異常,特別的,根據型別查詢時如果找到多個也會丟擲異常。

其他建立bean的方式
即工廠方式和靜態工廠方式,適合建立那些需要很多引數的物件

工廠方式:使用工廠物件的方法建立bean

靜態工廠方式:使用工廠類的靜態方法建立bean

這三種建立bean的方式中,開發人員一般直接使用建構函式方式,Spring本身或者其他第三方框架一般使用工廠方
式或靜態工廠方式。

bean的作用域
在Spring中,可以指定bean的作用範圍,預設是singleton(單例),即整個Spring容器執行期間該bean定義只會
建立一個Java物件。

使用scope屬性指定bean的作用域,可選值如下:
singleton:單例
prototype:原型,每次從容器中獲取時都返回新的物件
request:對於每個HTTP請求都會建立一個新的物件
session:每個HTTP會話建立一個新的物件
globalSession:每個HTTP全域性會話建立一個新的物件
application:每個ServletContext建立一個新的物件

雖然bean的作用域有多種,但只使用singleton和prototype已經滿足絕大部分的需求,其他很少使用
有時候也把bean的作用域說成生命週期(含義很相似),另外生命週期也指bean從建立到銷燬的過程(大家需要
知道這個情況)。

依賴注入
Spring可以把beanA所依賴的其他bean或者普通值(int、String)注入到beanA中,即依賴注入——DI
(Dependency Inject)。

基於setter方法的注入
使用<property>標籤完成注入,可以使用ref屬性指定依賴的bean的名稱,也可以使用value屬性注入普通值
(int、String等),甚至還可以注入集合。

基於建構函式的注入
<constructor-arg>標籤用來給建構函式注入引數,可以使用index屬性指定引數的索引位置,也可以使用name
屬性指定引數的名稱。
setter方式的注入比建構函式方式的注入更常用一些。

控制反轉(IoC)
在使用Spring之前,開發人員需要自己建立物件,並手動把依賴設定到物件中;現在,只需要通過配置,就可以把
建立物件、注入依賴的操作交給Spring去完成,這種改變稱為控制反轉——IoC(Inversion of Control)。其實
IoC和DI幾乎是等價的,不用刻意區分。
具有IoC功能的容器被稱為IoC容器,所以Spring容器也是IoC容器。現在,ApplicationContext物件可以稱為
Spring上下文物件、Spring容器、bean容器、IoC容器等。
控制反轉把物件的建立和使用分離開來(解耦合),讓開發人員可以更加專注於實現業務邏輯,另外還使得專案更
易維護和擴充套件。

bean定義的其他配置項
abstract屬性可以把bean定義成抽象的,用來被其他bean繼承,本身並不會建立物件
parent屬性用來指定要繼承哪個bean定義
init-method屬性用來指定建立bean物件後執行的初始化方法(值為方法名)

bean的總的建立過程為:
1 Spring掃描並儲存配置檔案中的bean定義
2(開始依次建立物件)建立一個物件之後,如果所有的依賴都已存在,則注入所有依賴,然後執行init-method
(否則不注入也不執行init-method)。
3(等所有的物件都建立出來之後)為還沒有注入依賴的bean注入所有依賴,然後執行init-method
可以簡化為:建立物件—> 注入依賴 —> init-method
destroy-method 用來指定銷燬bean前執行的銷燬方法,只對singleton作用域的bean有效(呼叫
AbstractApplicationContext的destroy()可以測試出效果)。

AOP
代理
代理是指使用一個新類代替另一個類,並在另一個類原有功能的基礎上進行增強處理。實現代理的方式有兩種:
JDK動態代理和CGLIB代理。

目標類:原來的類,將要被新類代替的類
目標方法:目標類的方法,將要被增強的方法
代理類:提供功能增強的新類,將要代替目標類

JDK動態代理
JDK動態代理是JDK內建的功能,基於介面在程式執行的時候動態的生成代理類。在JDK動態代理中目標類和代理類
實現相同的介面,是兄弟關係。

JDK動態代理

具體實現步驟如下:
1 必須要有介面
2 目標類
3 用來對目標方法進行增強的InvocationHandler
傳入目標物件的目的是可以執行目標方法
invoke方法的proxyObject參數列示代理類物件,method表示被呼叫的介面方法,args表示方法呼叫時傳入的引數
列表
method.invoke(targetObject,args) 表示執行目標方法
可以在目標方法執行前進行預處理
可以在目標方法執行後進行後處理
當使用代理類物件呼叫方法時,invoke方法就會被呼叫,從而實現增強處理
4 使用Proxy工具類生成代理類物件
newProxyInstance方法可以直接返回生成的代理類的物件
生成代理類時需要目標類的類載入器、目標類實現的介面、增強處理實現
由於JDK代理是基於介面實現的,代理類只能對目標類的介面方法進行增強,不能對目標類獨有方法進行增強;而且
增強的方法都是public方法
由於介面繼承了Object類,所以Object類的public方法也會被增強(除了getClass方法)

CGLIB代理
CGLIB(Code Generation Library)是高效能高質量的Java程式碼生成庫,可以在程式執行時擴充套件類。CGLIB可以
直接使用目標類生成代理類,不需要藉助介面,所以目標類和代理類之間是父子關係

CGLIB代理

CGLIB生成代理類時很多地方和JDK動態代理相似,步驟如下:
1 目標類
2 用來對目標方法進行增強的MethodInterceptor
methodProxy包含目標類、代理類、被呼叫的方法等資訊
3 使用Enhancer工具類生成代理類物件
CGLIB可對除private以外的方法進行增強,另外注意不要使用final修飾類或者方法
和JDK動態代理相比,CGLIB生成代理類物件的過程慢,但代理類物件的效能高,非常適合生成單例類的代理物件。
不過由於提倡使用介面程式設計,JDK動態代理也是非常常用的。

AOP的概念
AOP(Aspect-Oriented Programming),面向切面程式設計,是一種程式設計思想,是OOP的補充
AOP是在OOP的基礎上在程式設計的時候把公共的非業務邏輯操作抽取出來,然後使用代理的方式再把公共操作新增回去。
AOP的好處是讓公共操作和業務邏輯相分離(解耦合),既方便公共程式碼的編寫和管理,也方便業務邏輯的實現,
極大的簡化了開發過程。

AOP的一些概念:
Aspect 切面,使用Java類表示,用來存放公共操作抽取成的方法
Advice 通知,其實就是公共操作抽取成的方法

通知有五種型別:
Before                 在目標方法執行前執行
AfterReturning     在目標方法正常返回後執行
AfterThrowing      在目標方法丟擲異常後執行
After                    在目標方法執行後執行(無論是正常返回還是丟擲異常)
Around                在目標方法執行前和執行後都可執行

Join point 連線點,程式碼中可被插入通知的點,比如方法呼叫、屬性訪問、異常處理等,但Spring AOP只支援
方法呼叫連線點。
Pointcut       切入點,用來指定哪些連線點將被插入通知(哪些方法是目標方法)
Target          目標物件(被代理物件)
Proxy           代理物件
Weaving      織入,把通知和目標方法連線起來的過程稱為織入

Spring AOP
Spring AOPAOP的一種實現,基於代理(JDK動態代理和CGLIB代理),配合Spring容器,在執行時完成織入。
程式設計步驟
1 準備好目標類和目標方法
2 準備好切面類和通知:通知型別需要通過配置指定
3 beans.xml:目標物件和切面物件都需要先配置成bean才有效果

JoinPoint類
通知方法的第一個引數可宣告為JoinPoint型別,通過該引數可訪問目標物件、目標方法簽名、目標方法引數等。
特別的,當通知型別是Around時,可以使用子類ProceedingJoinPoint,方便控制是否執行目標方法,以及何時
執行目標方法。

切入點表示式
切入點使用切入點表示式指定哪些方法是目標方法。切入點表示式有多種型別,最常用的是execution,此外還有
@target、@annotation等。
execution用來描述目標方法的簽名,由6個部分組成:訪問修飾符;返回值型別 ;類;方法名(引數列表); 異常
宣告。
除了返回值型別、方法名、引數列表這三部分不可省略外,其餘部分都可省略。

各部分常用寫法如下:
訪問修飾符:一般省略,表示任意,但受代理方式的限制(CGLIBprivate方法無效)
返回值型別:*  表示任意
類的包:包全名、字首*..(某包和其子孫包)
類的類名:   類名、字首**
方法名:       方法名、字首**
引數列表:   ..  表示任意
異常宣告:一般省略,表示任意
通知方法不會被自己或其他通知增強,同一個目標物件中的方法相互呼叫時,被呼叫的方法這次呼叫不會被增強(被
其他物件的方法呼叫時會被增強)。
@target描述了標註了某註解的類的所有方法
@annotation描述了標註了某註解的方法
切入點表示式還可使用 &&  ||  ! 進行邏輯運算
注意:&在xml中需要寫成&amp;

SpringAOP實現機制
1 在建立Spring容器時,Spring會讀取並儲存切面配置資訊。建立bean後,如果這個bean匹配了切入點表示式,
Spring就會建立其代理物件代理這個bean。
2 使用代理bean第一次呼叫某個目標方法時,Spring會把所有匹配的通知和目標方法按照通知型別有序的組成一個
呼叫鏈,並把此呼叫鏈快取起來以便重複使用,然後執行此呼叫鏈。

其他通知型別

after-returning通知
<aop:after-returning>標籤的returning屬性值需要和通知方法第二個引數的引數名一致
after-returning型別的通知會在目標方法正常結束後執行,如果目標方法丟擲異常則不執行。

after-throwing通知
切面方法的第二個引數可以是異常型別,表示目標方法丟擲的異常,而且只有目標方法丟擲此異常類或其子類時,
才會執行切面方法。
<aop:after-throwing>標籤的throwing屬性值需要和切面方法的第二個引數的引數名一致。

after通知
通知方法會在目標方法結束後執行(無論目標方法是正常結束還是丟擲異常),並且不可訪問目標方法的返回值和
丟擲的異常。

around通知
通知方法可以進行預處理和後處理,還可決定呼叫鏈是否繼續執行。
通知方法的返回值應該宣告為Object型別,第一個引數應該宣告為ProceedingJoinPoint,並且應該宣告丟擲
Throwable異常型別。

AOP其他
AspectJ
除了Spring AOP,Spring還整合了第三方的AOP實現——AspectJ。AspectJ完整實現了AOP思想,有自己的編譯器,
在程式碼編譯階段完成織入。Spring AOP和Spring對AspectJ的整合相互獨立,互不影響。

強制讓Spring AOP使用CGLIB生成代理
對於實現了介面的目標類,Spring AOP預設會使用JDK動態代理,這時目標類的非介面方法就不會被增強,可以通過
配置強制讓Spring AOP使用CGLIB生成代理。

Spring對資料庫訪問的支援
宣告式事務管理
Spring內建了基於Spring AOP的宣告式事務管理,以配置的方式統一管理整個專案的事務,極大的簡化了開發人員
的工作。宣告式事務管理也是Spring的核心模組之一。
配置步驟:
1 配置資料庫連線池
2 根據運算元據庫的方式選擇對應的事務管理器
3 通過切入點表示式指定哪些方法需要織入事務,專案中一般為service包下的類的方法
4 指定事務屬性,如 是否只讀、傳播行為、隔離級別等
<aop:advisor>是舊版本Spring提供的一種織入方式,現在基本上只用來織入事務。

事務管理器
訪問資料庫的方式有兩類:直接使用JDBC和通過ORM框架訪問。其中ORM框架常見的有Mybatis、Hibernate、JDOJPA等。
Spring提供了多種型別的事務管理器以便對這些資料庫訪問方式提供事務管理支援,比如提供了
DataSourceTransactionManager來支援JDBC和Mybatis等,提供了HibernateTransactionManager來支援
Hibernate,等等。

事務傳播行為
required:如果當前有事務,就使用當前的事務,如果沒有,就開啟新事務
supports:如果當前有事務,就使用當前事務,如果沒有,則不開啟事務
requires_new:如果當前有事務,則掛起當前事務,並開啟新事務;否則直接開啟新事務
not_supported:如果當前有事務,則掛起當前事務
nested:如果當前有事務,則開啟一個巢狀事務;如果當前沒有事務,開啟新事務
mandatory:如果當前沒有事務,則丟擲異常
never:如果當前有事務,則丟擲異常

事務隔離級別
事務四大特性有
原子性:事務下的操作要麼全部成功,要麼全部回滾
一致性:事務前後資料庫都要處於一致狀態(轉賬前後兩個賬戶的總金額一致)
永續性:事務對資料的修改是持久的(即使資料庫檔案損壞也可通過日誌等恢復)
隔離性:多事務併發訪問時可能會造成資料安全問題,需要把事務隔離起來(加鎖)

事務的隔離性會導致資料庫併發訪問效能降低,但也得保證資料的安全,所以資料庫就提供了多種隔離級別以便針對
不同的應用場景使效能和安全都得到兼顧。

不同事務隔離級別的併發訪問效能和資料安全性都不同,常見資料安全問題如下:
髒讀:事務A讀到了事務B未提交的資料(即使事務沒有提交,SQL更新語句也會修改表)
不可重複讀:事務A前後兩次讀取的同一行資料不同(期間事務B修改了這行資料並提交)
幻讀:事務A刪除表中全部資料後再次查詢發現還有資料沒刪除(期間事務B插入新資料)

有四種資料庫隔離級別:
read_uncommitted:  完全沒有隔離,會出現髒讀、不可重複讀和幻讀
read_committed:      簡單隔離,不會出現髒讀
repeatable_read:     中度隔離,不會出現髒讀、不可重複讀
serializable:             完全隔離,不會出現髒讀、不可重複讀和幻讀

MySQL的預設隔離級別是repeatable_read、Oracle的預設隔離級別是read_committed
Spring在事務管理中預設使用當前資料庫的隔離級別(即isolation="DEFAULT"),在實際使用時如果沒有特殊要
求,預設即可。

事務回滾
預設情況下只有當事務方法丟擲了RuntimeException或者Error時事務才會回滾(丟擲檢查異常不會回滾),但可以
通過rollback-for屬性指定需要回滾異常型別。也可以通過no-rollback-for屬性指定不回滾的異常型別。

Spring對JDBC的簡單封裝
對於簡單專案可以直接使用JDBC運算元據庫。Spring提供了JDBCTemplate對JDBC操作進行了封裝,方便開發人員
使用。

其他
Resource資源介面
為了統一、方便的管理各種型別的資源,Spring提供了Resource資源介面以及眾多和資源型別相關的實現類,部分
實現類如下:
ClassPathResource:類路徑下的資源,內部使用classLoader.getResourceAsStream(path)的方式獲得資源的讀
取流。
FileSystemResource:檔案系統中的資源,內部使用new File(path)表示,並使用new FileInputStream(file)
的方式獲得資源的讀取流。
UrlResource:URL資源,內部使用new URL(path)表示,並使用url.openConnection().getInputStream()的
方式獲得資源的讀取流。

建立ApplicationContext時配置檔案路徑的處理方式:
1 如果路徑有classpath:字首,則使用ClassPathResource表示
2 如果路徑是URL,則使用URLResource表示
3 使用特定於ApplicationContext子類的方式表示

在配置資訊中使用佔位符
在XML或者註解配置中,可以使用 ${ propertyName } 的形式表示佔位符,Spring容器建立時會從properties文
件中獲取對應的值替換佔位符。
properties檔案使用<context:property-placeholder />標籤載入,location屬性指定檔案位置,多個檔案使用
逗號分隔,system-properties-mode屬性指定查詢方式,取值如下:
NEVER 只從指定的檔案中查詢
FALLBACK 預設值,先查詢指定檔案,如果沒有,再查詢系統屬性,即System.getProperties()
OVERRIDE 先查詢系統屬性,如果沒有,再查詢指定檔案
ENVIRONMENT 為相容舊版本而保留的,和OVERRIDE一致,但不建議再使用
如果最終也沒找到對應的屬性值,則會丟擲異常。

Spring表示式語言
Spring表示式語言,簡稱SpEL,語法和EL非常相似,但更加強大。SpEL雖然是Spring的一個模組,但可以脫離
Spring容器獨立使用,主要用來為Spring各個模組提供統一的表示式語言支援。

除了表示式語言的一般功能外,SpEL還支援方法呼叫、建立集合物件、字串模板等功能。在配置資訊中使用時可簡
化配置,但實際使用頻率很低,此處只簡單瞭解。
SpEL的格式是 #{ expression },要注意和配置資訊中的${ }佔位符區分開,它們是不同的技術

Spring任務排程
任務排程是指以固定頻率、固定延遲或者固定時刻的方式排程執行指定的任務
Spring內建了Spring Task並且整合了第三方任務排程框架Quartz,對任務排程提供了多種支援。

Spring Task
Spring Task 是Spring內建的任務排程實現,用法簡單方便
Spring配置檔案提供了task名稱空間來配置Spring Task相關資訊。

Spring Task 使用普通bean的方法作為任務方法,可以直接通過配置排程執行:
method指定要排程執行的任務方法
fixed-rate上次任務開始後間隔指定時間執行下一次(固定頻率)
fixed-delay上次任務完成後間隔指定時間執行下一次(固定延遲)
initial-delay 任務在建立好之後延遲多長時間開始第一次排程,預設立即開始排程
cron 使用cron表示式指定排程規則
Spring Task預設以單執行緒的方式排程執行所有任務,如果任務很多導致單個執行緒忙不過來,可以使用執行緒池。

注意:任務很多和一個任務很頻繁不一樣
Spring Task在固定頻率排程下,如果一個任務很頻繁就可能導致上次排程還沒執行結束但下次排程又該開始了,
這時Spring Task的處理方式是下次排程順延到上次排程執行結束後再執行。
一個<task:scheduled>標籤在任務排程期間使用的始終都是同一個任務bean物件。
如果任務bean依賴其他bean,可以直接注入進來

cron表示式
cron表示式用來指定排程規則,由6個或7個時間欄位按順序組成,並使用空格分隔:
秒 分 時 日期 月份 星期
秒 分 時 日期 月份 星期 年
注意:新版本的Spring Task只支援6個時間欄位的形式,不支援年
名稱      取值範圍      支援的有特殊含義的字元
秒          0-59              ,  -  /  *0-59              ,  -  /  *0-23              ,  -  /  *
日期       1-31              ,  -  /  *  ?  L  W
月份       1-12              ,  -  /  *
星期       1-7                ,  -  /  *  ?  L  #     (1表示星期日,2表示星期一)
特殊字元含義如下:
,      表示列舉       1,10,20(秒)表示第1秒,第10秒和第20-      表示範圍       2-6(星期)表示從星期一到星期五
/      表示增量       0/5(秒)表示每隔5*      表示每一個   *(時)表示每小時
?     為避免日期和星期衝突,在指定其中一個時,另一個使用?表示不指定
L     表示最後       6L(星期)表示某月的最後一個星期五
#     某月第幾個星期幾      7#2(星期)表示某月的第2個星期六
W    最近的有效工作日,9W(日期)表示如果9號在星期一到星期五之間,則就是9號;如果9號是星期六,則提前到
8號(星期五);如果9號是星期日,則順延到10號(星期一);注意不能跨月份。

Spring整合Quartz
Quartz是一個獨立的任務排程框架,Spring簡單封裝了Quartz,方便在Spring中使用
和Spring Task相比較而言,Quartz屬於重量級的任務排程框架,使用方式也稍複雜些:
1繼承QuartzJobBean編寫自己的任務類
2配置JobDetailFactoryBean,為任務類提供依賴的資料
3配置觸發器指定排程規則
4配置排程器執行排程
任務每次被排程執行時都會建立新的任務類物件。
Quartz的簡單觸發器按照固定頻率的方式進行排程,和Spring Task的區別是Quartz固定頻率排程時每次排程互不
影響,即使上次排程還沒執行完成,下次排程也會按時開始。
大部分情況下專案中使用Spring Task或者Quartz都是可以的,可根據具體的應用場景靈活選擇。

web專案中建立Spring容器
Spring提供了ContextLoaderListener這個servlet監聽器,用來在web專案啟動時建立Spring容器,並把建立好
的Spring容器儲存在ServletContext物件中。

註解方式配置Spring
使用註解把類標註為bean
Spring提供了@Component註解,相當於<bean>標籤,可以把類標註為bean。同時可以指定bean的name。name預設
為類名首字母小寫形式,如UserService的bean name為userService。
此外,還提供了@Controller、@Service、@Repository這三個註解,作用和@Component一樣,但可讀性更好,
可以表明bean在專案的哪個層(Web層、service層、DAO層)。

Spring的註解配置功能預設是關閉的,需要在beans.xml中使用<context:component-scan>標籤開啟。同時需要
使用base-package屬性指定到哪些包(及其子包)下去掃描註解,多個包之間可以使用逗號分隔。

此外Spring還提供了
@Scope指定bean的作用域
@PostConstruct指定bean的初始化方法(標註在初始化方法上)
@PreDestroy指定bean的銷燬方法(標註在銷燬方法上)

使用註解裝配bean
Spring支援使用@Autowired、@Resource給bean注入依賴bean,也支援使用@Value給bean注入普通值
注入依賴bean時會基於兩個方面:bean型別(以及泛型)和bean name

@Autowired優先基於型別注入
@Autowired可標註在欄位、任意方法、建構函式上,優先根據bean的型別到Spring容器中查詢並注入
如果找到多個型別匹配的bean(比如欄位的型別是父類,有多個子類bean),會進一步根據泛型篩選
如果還是不能只篩選出一個bean,則再以欄位名作為bean name進行篩選(也可以使用@Qualifier指定bean name)
如果最終也不能只篩選出一個bean,則丟擲異常(找不到bean時也會丟擲異常)
此外,@Autowired還可以注入ApplicationContext物件。

@Resource優先基於bean name注入
Spring還支援JSR-250標準中的@Resource,@Resource可以標註在欄位或者setter方法上,預設以欄位名作為
bean name(也可以手動指定bean name)到容器中查詢,如果沒找到,則再使用欄位型別進行查詢,也支援使用
泛型進一步篩選。
@Resource也可以注入ApplicationContext物件

對於@Autowired和@Resource,效果基本上是一樣的,專案中一般主要使用其中一個,另一個作為輔助。

@Value注入普通值
@Value可以注入普通值,比如String、int等,可標註在欄位、setter方法上,也可標註在標註了@Autowired的
建構函式或者方法的引數上面。
在注入時,可以直接使用常量值,也可使用佔位符或者Spring表示式。

使用註解配置AOP
Spring直接使用了AspectJ框架定義的一些註解:@Aspect、@Pointcut、@Before、@AfterReturning、
@AfterThrowing、@After、@Around等,但這些註解功能預設也是關閉的,需要使用<aop:aspectj-autoproxy/>
標籤開啟
@Aspect相當於<aop:aspect>,用來定義切面
@Pointcut相當於<aop:pointcut>,用來定義可重用的切入點,標註在方法上,使用被標註的 方法名() 的方式引用
@Before相當於<aop:before>,用來定義Before通知,可直接指定切入點表示式,也可引用@Pointcut定義的可
重用切入點表示式。

使用註解配置Spring Task
可以很方便的使用@Scheduled註解配置Spring Task,標註在bean的方法上即可,但同樣也需要使用
<task:annotation-driven>標籤開啟Spring Task註解支援。
@Scheduled(fixedRate=5000) 固定頻率
@Scheduled(fixedDelay=5000) 固定延遲
@Scheduled(cron="*/5 * * * * ?") cron表示式






相關文章