Spring-IoC(控制反轉)
一、 IoC
-
IoC是什麼?
IoC(Inverse of Control),即控制反轉,是一種程式設計思想。
通常new一個執行個體,控制權由程式員控制,而"控制反轉"是指new執行個體工作不由程式員來做而是交給Spring容器來做。
-
IoC有什麼用?
主要起到程式解耦作用。
以往我們都是以寫死的方式來完成對象的建立和生命周期管理,代碼不靈活、不利于擴充和維護。
而IoC的設計思想是以Spring容器為第三方,由它來管理應用中所有對象的建立和生命周期。
以生活舉例,IoC就好比,房東把房子交給中介托管。
二、IoC容器
DI(Dependency Insert),即依賴注入。
IoC容器是具有DI功能的容器。
IoC容器負責執行個體化、定位、配置應用程式中的對象及建立這些對象間的依賴。
spring提供了以下兩種不同類型的容器:
注:以下案例其實都可以用同一個配置檔案等,為了清晰各個步驟,我就都重複寫了
Spring BeanFactory容器
案例:
1、注入依賴 spring-context
2、建立一個類 MyBeanFactory.class
3、建立配置檔案 springioc_bean.xml
4、完善配置檔案
5、建立一個測試類 BeanFactoryTest.class
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
建立類
目錄結構
建立spring配置檔案:
完善配置檔案
建立測試類
測試結果
Spring ApplicationContext容器
案例:
1、注入依賴 spring-context
2、建立一個類 MyContext.class
3、建立配置檔案 springioc_context.xml
4、完善配置檔案
5、建立一個測試類 ContextTest.class
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
建立類
目錄結構
建立spring配置檔案
完善配置檔案
建立測試類
FileSystemXmlApplicationContext:基于檔案系統中XML檔案配置的應用程式上下文
ClassPathXmlApplicationContext:基于ClassPath路徑中XML檔案配置的應用程式上下文
測試結果
注:getBean()有兩種方式
bean 節點
上例中,配置檔案裡的bean節點,即spring bean定義,代表一個JavaBean對象。
容器建立bean,需要配置中繼資料。
bean節點的屬性:
屬性 | 描述 |
---|---|
class | 這個屬性是強制的,指定用來建立bean的bean類的classpath,即包名+類名 |
id | 對象id,id不可重複,指定唯一的bean辨別符 |
name | 對象名稱,name可以重複,如果重複将讀取最後一個 |
scope | 指定bean建立的對象的作用域 ①singleton:單例模式,預設的作用域,Spring 中的預設作用域,在IoC容器中僅存在一個執行個體。在建立容器時就同時自動建立了一個 bean 的對象,不管你是否使用,它都存在了,每次擷取到的對象都是同一個對象。 ②prototype:多例,每次從IoC容器中調用Bean時,都會傳回一個新的執行個體。在建立容器的時候并沒有執行個體化,而是當擷取bean的時候才會去建立一個對象,而且每次擷取到的對象都不是同一個對象。 ③request:每次Http請求都會建立一個新的Bean,該作用域僅适用于WebApplicationContext環境 ④session:同一個會話共享一個Bean,不同的會話使用不同的Bean,僅适用于WebApplicationContext環境 ⑤application:一般用于portlet應用環境,僅适用于WebApplicationContext環境 |
constructor-arg | 用來注入依賴關系 |
autowiring mode | 用來注入依賴關系 |
properties | 用來注入依賴關系 |
bean 節點 繼承
案例:
1、注入依賴 spring-context
2、建立兩個類 Son.class、Parents.class
3、建立配置檔案 springioc_beanextends.xml
4、完善配置檔案
5、建立一個測試類 BeanExtendsTest.class
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
建立兩個類
目錄結構
建立spring配置檔案
完善配置檔案
建立測試類
測試結果(子定義繼承了父定義的屬性)
bean 屬性注入的幾種方式
- 構造函數注入(constructor-arg)
- set方法注入(property)
- 自動裝配注入(bean的autowire屬性)
類型:
no 預設,不自動裝配
byType 通過類型查找對象,如果相同類型的對象有多個,會出現異常
byName 通過名稱查找對象,如果找不到對應的id或name的對象,會出現空指針異常
constructor 通過構造方法裝配
注解配置IoC
注解 | 描述 |
---|---|
@Component | 元件,被标記的類會被Spring掃描到,交給Spring容器進行管理 |
@ComponentScan | 元件掃描,标記在配置類上,用于掃描某一個包下帶 @Component的類 |
@Configuration | 配置類,标記在類上,該類作為配置類代替xml |
@Value | 注入值類型資料,配置屬性或set方法上 |
@Autowire | 自動裝配,預設按類型進行注入 |
@Qualifier | 标記名稱,配置在類和注入屬性上,用于區分類型相同的對象。@Autowired 和 @Qualifier 注解可以用來删除混亂。 |
@Resource | 自動裝配,類似Autowire,預設按名稱注入,名稱沒有再按類型注入 |
@Repository | 類似@Component,标記DAO實作類 |
@Service | 類似@Component,标記Service實作類 |
@Controller | 類似@Component,标記Controller類 |
案例:
目錄結構
給每個接口的一個實作類加上@Component注解
給Computer類添加@Component注解,值類型屬性用@Value注入,引用類型用@Autowired注入
這裡報錯了
因為autowire預設按類型注入,而這裡同類型接口的實作類有兩個,是以會沖突報錯。此時隻需要在每個實作類上加上@Qualifier區分即可
配置類
運作結果
IoC實作原理
通過自定義注解+反射機制實作
自定義注解案例:
目錄結構
建立兩個注解類MyValue、MyComponent