Spring IoC(控制反轉(zhuǎn))之注解配置
1. 前言
上兩節(jié),我們學(xué)習(xí)了 Spring IoC 的 xml 配置實(shí)現(xiàn),整理了 xml 方式的實(shí)現(xiàn)步驟,并且模擬了 Spring 的容器如何加載解析 xml 配置文件,那么我們發(fā)現(xiàn)一點(diǎn)現(xiàn)象:
對(duì)于 Spring 的 bean 管理而言,如果全部通過(guò) xml 文件實(shí)現(xiàn)的話,配置文件的內(nèi)容未免過(guò)于臃腫。因?yàn)閷?duì)于一個(gè)類(lèi)的實(shí)例化,就需要一個(gè) bean 標(biāo)簽。
這樣的話,一個(gè)大型工程下來(lái),有那么幾百個(gè),幾千個(gè)類(lèi),Spring 的 xml 文件維護(hù)起來(lái),成本實(shí)在太高。
疑問(wèn)導(dǎo)出:
Spring 能否有更方便的方式實(shí)現(xiàn) IoC 呢?Spring 提出了兩種 IoC 實(shí)現(xiàn)方式,一種是基于配置文件,一種是基于注解形式。
本節(jié),我們學(xué)習(xí)下 Spring IoC 的注解形式是如何實(shí)現(xiàn)的。
2. 案例實(shí)現(xiàn)
2.1 步驟介紹
回顧 Spring IoC 的 xml 實(shí)現(xiàn)步驟:
? 1. 使用 new 關(guān)鍵字對(duì) ClassPathXmlApplicationContext
做初始化;
? 2. 在初始化容器對(duì)象的構(gòu)造傳入 xml 配置文件的位置 ;
? 3. 在配置文件中通過(guò) bean 標(biāo)簽可以對(duì)類(lèi)進(jìn)行描述:類(lèi)的路徑、類(lèi)的標(biāo)識(shí)、類(lèi)的構(gòu)造參數(shù)等等。
注解實(shí)現(xiàn) IoC 的思路分析:
? 1.Spring 容器一樣需要初始化;
? 2. 一樣需要傳入 xml 配置文件 ----- 需要描述清楚 需要被實(shí)例化的類(lèi)都有哪些;
? 3.xml 文件中 不需要使用 bean 標(biāo)簽描述被實(shí)例化的類(lèi) ------ 使用注解實(shí)現(xiàn) IoC 管理目的就是為了簡(jiǎn)化 bean 標(biāo)簽的配置。
疑問(wèn)導(dǎo)出:
如果是 xml 文件方式實(shí)現(xiàn) IoC ,加載 xml 文件的 bean 標(biāo)簽就已經(jīng)知道,需要被實(shí)例化的對(duì)象,那么如果不使用 bean 標(biāo)簽描述,Spring 框架如何得知哪些類(lèi)需要被容器管理呢?
核心思想:
開(kāi)發(fā)人員無(wú)需使用 XML 來(lái)描述 bean ,而是將配置移入 Java 的類(lèi)本身,通過(guò) Spring 支持的組件掃描來(lái)實(shí)現(xiàn)。
看官稍等… 馬上開(kāi)始我們的案例實(shí)現(xiàn)。
2.2 工程實(shí)現(xiàn)
創(chuàng)建工程:
為了區(qū)分 xml 工程,坐標(biāo)名稱(chēng)換成 spring_an ,其實(shí)無(wú)所謂,大家自行創(chuàng)建即可。
導(dǎo)入依賴(lài):
依賴(lài)的坐標(biāo)跟 xml 的工程坐標(biāo)一致即可,無(wú)需導(dǎo)入多余的依賴(lài)。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
項(xiàng)目代碼:
為了測(cè)試,在工程內(nèi)部創(chuàng)建 UserDao
的接口和 UserDao
的實(shí)現(xiàn)類(lèi) UserDaoImpl
。
UserDao
代碼如下:
public interface UserDao {
public void saveUser();
}
UserDaoImpl
的實(shí)現(xiàn)類(lèi)代碼如下:
@Repository
public class UserDaoImpl implements UserDao {
public void saveUser() {
System.out.println("執(zhí)行dao的保存方法");
}
}
注意事項(xiàng): 由于我們是基于注解的方式實(shí)現(xiàn)對(duì) bean 的管理,所以在實(shí)現(xiàn)類(lèi)上面需要添加一個(gè)注解 @Repository,此注解的作用是為了 Spring 的容器啟動(dòng)后,
需要要自動(dòng)檢測(cè)這些被注解的類(lèi)并注冊(cè)相應(yīng)的 bean 實(shí)例到容器中。
Spring 的核心配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.wyan.dao"></context:component-scan>
</beans>
上面是本案例的配置文件,那么可以看出跟 xml 的配置文件有很大的區(qū)別:
?配置節(jié)點(diǎn):context-component-scan
標(biāo)簽,這是 Spring 框架自定義的 xml 標(biāo)簽,通過(guò) base-package
的屬性,指明需要被自動(dòng)掃描實(shí)例化的類(lèi)所在位置。
如上圖所示,我們?cè)?com.wyan.dao 下的類(lèi)是需要掃描自動(dòng)注入容器的。
小細(xì)節(jié):不是在 com.wyan.dao 下的所有類(lèi)都會(huì)自動(dòng)注入到容器,而是要搭配注解:比如我們的 @Repository 當(dāng)然還有其余的注解,我們后面章節(jié)會(huì)詳細(xì)講解。
測(cè)試類(lèi)測(cè)試結(jié)果:
代碼解釋:
測(cè)試類(lèi)其實(shí)跟 xml 的方式一模一樣,我們本次測(cè)試的目的一樣也是通過(guò) Spring 容器管理注冊(cè)的 bean 對(duì)象,只不過(guò)對(duì)象的實(shí)例化方式換成了注解,那么我們看到成功輸出在控制臺(tái)的測(cè)試語(yǔ)句,說(shuō)明案例搭建完成。
3. 小結(jié)
本節(jié)帶著大家使用注解的方式,實(shí)現(xiàn)了 Spring 對(duì)于 bean 的管理。
那么回顧下注解開(kāi)發(fā)的步驟和注意點(diǎn):
- Spring 容器初始化一樣需要 xml 文件,目前是 xml 文件搭配注解管理 bean 并不是純注解開(kāi)發(fā);
- Spring 的 xml 配置文件中使用
context:component-scan
標(biāo)簽指定注冊(cè) bean 的類(lèi)所在目錄位置; - 自定義編寫(xiě)的 Java 類(lèi),如果需要被自動(dòng)掃描注入容器,必須搭配注解。
學(xué)習(xí)的苦只是一時(shí)之苦,學(xué)不到的苦是一世之苦,與君共勉…