天天看點

Spring IoC 容器1.Ioc 概述Java 反射Spring 資源通路BeanFactory 和 ApplicationContextBean 的生命周期

1.Ioc 概述

Ioc (Inverse of Control) 是 Spring 容器的核心,字面意思為控制反轉,包括控制和反轉兩方面内容。具體指的是某一接口具體實作類的選擇控制權從調用類中移除,轉交給第三方決定,即由 Spring 容器借由 Bean 配置來進行控制。 DI(Dependency Injection) 的概念也可以用來代替 IoC,即讓調用類對某一接口實作類的依賴關系由第三方注入。

(1)Ioc 的類型

Ioc 主要劃分為3種類型:構造函數注入、屬性注入、接口注入。

<1> 構造函數注入

通過調用類的構造函數,将接口實作類通過構造函數變量闖入。

<2> 屬性注入

屬性注入可以有選擇地的通過 Setter 方法完成調用類所需依賴的注入。

<3> 接口注入

将調用類所有的依賴注入的方法抽取到一個接口中,調用類通過實作該接口提供的相應的注入方法完成注入。接口注入需要增加類的數目,不提倡。

(2)通過容器完成依賴關系的注入

Spring 即一個容器,它通過配置檔案或注解描述類與類之間的依賴關系,自動完成類的初始化和依賴注入工作。

Java 反射

通過程式化方式間接對 Class 進行操作。Class 檔案由類裝載器裝載後,在 JVM 中形成一份描述 Class 結構的元資訊對象。java 允許使用者借由這個元資訊對象直接調用 Class 對象。

簡單執行個體:

ClassLoder loader = Thread.currentThread().getContextClassLoader();//擷取目前線程的ClassLoader
Class clazz = loader.loadClass("car");//通過全限定類名裝載反射執行個體

Constructor cons = clazz.getDeclaredConstructor((Class[])null);
Car car = (Car)cons.newInstance();//擷取類的預設構造器對象,并通過其執行個體化Car

Method setColor = clazz.getMethod("serColor",String.class);
setColor.invoke(car,"black");//通過反射方法設定屬性
           

類裝載器 ClassLoader

ClassLoader 工作機制

尋找類的位元組碼檔案并構造出類在 JVM 内部表示對象的元件。

類轉載器把類裝入 JVM 的步驟:

(1)裝載

(2)連結

(3)初始化

JVM 在運作時會産生3個 ClassLoader:根裝載器、ExtClassLoader、AppClassLoader。根裝載器時 ExtClassLoader 的父裝載器,ExtClassLoader 是 AppClassLoader 的父裝載器。根裝載器負責 JRE 核心類庫裝載,C++ 編寫,Java 中看不到。ExtClassLoader 負責裝載 JRE 拓展目錄 ext 中的 JAR 包。AppClassLoader 負責裝載 Classpath 路徑下的類包。

Spring 資源通路

資源通路接口 Resource

Resource 主要方法:

boolean exists():是否存在

boolean isOpen():是否打開

URL getURL() throws IOException:傳回資源的 URL

File getFile() throws IOException:傳回資源的 File 對象

InputStream getInputStream() throws IOException:傳回資源對應的輸入流

資源加載

不顯示使用 Resource 實作類的情況下,僅通過資源位址的特殊辨別通路對應資源

BeanFactory 和 ApplicationContext

Spring IoC 完成底層的 Bean 之間的依賴關系建立,還提供 Bean 執行個體緩存、生命周期管理、Bean 執行個體代理、事件釋出、資源裝載等。

BeanFactory 是 Spring 的核心接口,提供 IoC 配置機制,面向 Spring 本身;ApplicationContext 建立在 BeanFactory 基礎之上,提供面向應用的功能,面向使用 Spring 的開發者。

BeanFactory

BeanFactory 最主要的方法就是 getBean(String beanName),該方法從容器中傳回特定名稱的 Bean。

BeanFactory 的接口 XmlBeanDefinitionReader 通過 Resource 裝載 Spring 配置資訊并啟動 IoC 容器,然後就可以通過 BeanFactory#getBean(beanName) 方法從 IoC 容器中擷取 Bean。

對于單執行個體(singleton)的 Bean 來說,第二次使用 getBean() 擷取該 Bean 時,将直接從 IoC 容器緩存中擷取該 Bean。DefaultSingletonBeanRegistry 類提供一個用于緩存單執行個體 Bean 的緩存器 (HashMap 實作)。

ApplicationContext

ApplicationContext 的主要實作類是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext,前者預設從類路徑加載配置檔案,後者預設從檔案系統中裝載配置檔案。

ApplicationContext 會在初始化時就執行個體化所有單執行個體的 Bean。而 BeanFactory 隻有在第一次通路某個 Bean 時才執行個體化目标 Bean。

Spring 子項目 JavaConfig 提供了基于注解的配置方式

Spring 為基于注解類的配置提供了專門的 ApplicationContext 實作類:AnnotationConfigApplicationContext

基于 Groovy 的配置方式

Spring 為基于 Groovy 類的配置提供了專門ApplicationContext 實作類:GenericGroovyApplicationContext

WebApplicationContext

WebApplicationContext 可以獲得 ServletContext 的引用。

非 Web 環境中 Bean 隻有 singleton 和 prototyte 兩種作用域,而WebApplicationContext 添加了三個新的作用域:request、session、global session。

WebApplicationContext 隻有在擁有 Web 容器的前提下才能啟動工作

父子容器

通過 HierarchicalBeanFactory 接口,Spring IoC 容器可以建立父子層級關聯的容器體系,子容器可以通路父容器,而父容器不能通路子容器。

Bean 的生命周期

BeanFactory 中 Bean 的生命周期

(1)通過 getBean()請求 Bean 時,調用 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation() 方法。

(2)執行個體化 Bean。

(3)調用InstantiationAwareBeanPostProcessor 接口的 postProcessAfterInstantiation() 方法。

(4)設定 Bean 屬性前調用InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues()方法。

(5)調用 Bean 的屬性設定方法設定屬性值。

(6)調用 setBeanName()接口方法。

(7)調用 setBeanFactory()接口方法。

(8)調用 BeanPostProcessor 的 postProcessBeforeInitialization(Object name,String beanName)方法。AOP,動态代理都通過 BeanPostProcessor 實施。

(9)調用 afterPropertiesSet()方法。

(10)執行 Bean 的初始化方法。

(11)對 Bean 加工處理。

(12)将 “prototype” 的 Bean 傳回給調用者,Spring 不再負責這些 Bean 生命管理。将 “singleton” 的Bean 放入 IoC 容器的緩存池中。并将 Bean 引用傳回給調用者,Spring 繼續負責這些 Bean 生命管理。

(13)“singleton” Bean 的釋放資源,記錄日志操作。

(14)“singleton” Bean 的銷毀。

ApplicationContext 中 Bean 的生命周期

如果 Bean 實作了 ApplicationContextAware 接口,則會增加一個調用該接口的方法 setApplicationContext() 的步驟。

  • 《精通 Spring4.x 企業應用》學習筆記*