Spring5.0源碼學習系列之核心技術IoC概述(三)
提示:Spring官網對Spring的主要技術做了比較詳細的介紹,詳情參考Spring官網spring core文檔,IOC實作是springframework的一個核心功能,本部落格對spring ioc進行比較大概的描述,僅作為學習源碼之前的科普
文章目錄
- 前言
- 一、IOC是什麼?
- 二、IOC容器的作用
- 三、IOC和DI差別
- 四、Spring容器概述
- 五、如何使用IOC容器?
- 5.1、配置中繼資料
- 5.2、執行個體IOC容器
- 5.3、使用IOC容器
- 六、Spring Bean概述
- 6.1、Spring中的Bean概述
- 6.2、執行個體Bean的方式
- 七、定義SpringBean
- 7.1、定義Spring Bean
- 7.2、Bean作用域
- 7.3、Bean懶加載模式
- 八、Spring生命周期
- 九、Spring後置處理器
- 十、什麼是循環依賴?
- 歸納
前言
提示:Spring架構源碼是java領域比較好的源碼,原因是這款架構架構設計很好,架構拓展性靈活,這就是spring架構流行的原因之一。而Ioc(控制反轉)子產品和aop是springframework的兩個核心功能。ioc和aop是一種技術思想,早在springframework架構開發之前就已經提出來了,不過更偏向于理論,而spring在技術層面對這兩個思想做了很好的實作(java領域)
提示:以下是本篇文章正文内容,下面案例可供參考,僅作為學習ioc實作源碼之前的科普,因為ioc源碼比較複雜,學習源碼之前要一些必要的了解,首先應用都不熟悉,看源碼肯定是看不懂的,是以要先通過學習了解熟悉spring的ioc實作
一、IOC是什麼?
IOC:Inversion of controll(控制反轉 / 反轉控制),ioc是一種技術思想,在spring架構開發之前就已經提出來的,spring架構對ioc技術思想進行了很好的實作
對控制反轉的了解:控制反轉(IOC)可以了解為擷取依賴對象的方式反轉過來,有反轉就有“正轉”,所謂“正轉”可以這樣了解,“正轉”就是正常的擷取對象方式,比如類A依賴于類B,在類A中要擷取類B,就是new一個B對象既可,這種就是“正轉“,這種方法對依賴對象的管理擷取,或者說是由類A去觸發的。而反轉的情況是對依賴對象的控制都交給spring ioc容器,對象的建立管理都給ioc容器,需要什麼對象,直接通過ioc容器拿既可
不依賴于IOC的情況:直接通過new擷取依賴對象
有Spring IOC容器的情況:所有對象的建立管理都給spring ioc容器控制,需要什麼對象直接找ioc容器拿,如圖:
為什麼叫控制反轉?
- 控制:指的是對依賴對象控制,執行個體,管理
- 反轉:對依賴對象的控制交給外部環境,也即Spring IOC容器
二、IOC容器的作用
引用其它部落格對ioc解的诠釋:http://www.52codes.net/article/40150.html,從圖可以看出ioc容器其實就是用于解耦的,展現了oop思想
ps:沒有IoC的程式中我們使用面向對象程式設計對象的建立與對象間的依賴關系完全寫死在程式中
三、IOC和DI差別
DI:Dependancy Injection(依賴注入),控制反轉(IOC)和依賴注入(DI)其實描述的是同一件事,隻不過是角度不同
- 控制反轉(IOC)站在對象角度,強調對象的控制交給(反轉給)IOC容器,IOC容器控制對象的執行個體、管理
- 依賴注入(DI)站在IOC容器的角度,說明的是IOC容器将依賴對象注入到IOC容器,假如類A聲明了類B的屬性,在ioc容器啟動時候就需要将類B對象注入給類A
四、Spring容器概述
去Spring官網找到IOC容器的相關說明文檔,發現官方文檔還是比較詳細的,雖然沒有對Spring架構源碼進行分析,不過也對IOC進行了很詳細的說明,詳情可以參考官方文檔,本部落格參考官方文檔進行摘要說明:
Spring官網對Spring ioc容器的描述:
This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) [1] principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes, or a mechanism such as the Service Locator pattern.
其實意思也和前面說明的相近,也是說明控制反轉(IOC)其實就是将依賴對象的控制反轉給IOC容器
官網的圖檔,描述了spring容器管理對象的大概過程:
五、如何使用IOC容器?
也即官方文檔說明的三個步驟:
翻譯過來就是:
- 配置中繼資料
- 執行個體IOC容器
- 使用IOC容器
ok,跟着官方文檔,進行學習:
5.1、配置中繼資料
官網介紹了兩種方式:也即基于注解的,另外一種是基于java配置的
基于注解的,主要是spring官方的提供的主鍵,比如經常用的@Autowired主鍵等等,詳情可以參考官方文檔
基于java配置的有兩種方法,一種是寫一個
@Configuration
配置類,一個是通過xml配置檔案,詳情可以參考官方文檔:
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
用思維導圖,簡單畫圖:
5.2、執行個體IOC容器
執行個體一個Spring IOC容器,官網的例子是:
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans>
簡單做下歸納:
5.3、使用IOC容器
執行個體好IOC容器之後,既可擷取對應的依賴對象:
六、Spring Bean概述
6.1、Spring中的Bean概述
Bean概述:Spring中的Bean指Beandefinition,Beandefinition是經過Spring容器執行個體的一個執行個體
6.2、執行個體Bean的方式
官網代碼示例:靜态工廠執行個體
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
工廠執行個體:
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
七、定義SpringBean
7.1、定義Spring Bean
Spring官網給出了如何定義一個Spring Bean:
本部落格用思維導圖做下歸納:
7.2、Bean作用域
範圍 | 描述 |
單例(Singleton) | (預設)單例的beanDefinition |
原型(prototype) | 多例,多個執行個體的beanDefinition |
請求(request) | 單例的, 作用于HTTP 請求的生命周期 |
會話(session) | 單例的, 作用Http會話的聲明周期 |
應用(application) | 單例的,應用于ServletContext生命周期 |
網絡socket(webSocket) | 單例的,應用于Websocket環境 |
單例模式的圖例,圖來自Spring官網
原型模式,也稱之為多例模式,圖例來自Spring官網:
7.3、Bean懶加載模式
懶加載(Lazy-initialized beans):懶加載模式是bean在第一次調用時候被執行個體,而不是spring容器啟動時候,預設是不開啟的,( A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.),通過改配置lazy-init=“true”
八、Spring生命周期
Spring的生命周期是Spring架構的一個比較重要的方面,不過内容比較多,是以本部落格隻是簡單進行描述
九、Spring後置處理器
後置處理器是Spring架構的一個比較重要的方面,不過内容比較多,是以本部落格隻是簡單進行描述
十、什麼是循環依賴?
兩個及以上的類互相調用依賴,形成閉環,Spring架構檢測到這種場景會抛 BeanCurrentlyInCreationException,提前暴露對象的方法