初探Spring框架之———IOC

一、首先解釋一下什麼是Spring框架,以及Spring框架的作用

1、Spring框架:Spring是一個full-stack(一站式)的輕量級開源框架,以IOC(Inverse Of Control: 控制反轉)和 AOP(Aspect Oriented Programming:面向切面編程)爲內核。簡單來說,Spring是一個分層的JavaSE/EE full-stack 輕量級開源框架。

2、作用:解決企業應用開發的複雜性

3、優點:

1):方便解耦,簡化開發 (高內聚低耦合)

Spring就是一個大工廠(容器),可以將所有對象創建和依賴關係維護,交給Spring管理
spring工廠是用於生成bean

2):AOP編程的支持

Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能

3):聲明式事務的支持

只需要通過配置就可以完成對事務的管理,而無需手動編程

4):方便程序的測試

Spring對Junit4支持,可以通過註解方便的測試Spring程序

5):方便集成各種優秀框架

Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持

6):降低JavaEE API的使用難度

Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低

二、什麼是IOC?

1、IOC(Inversion of Control):就是控制反轉。控制反轉指的就是將對象的創建權交給了Spring來管理,其作用是實現了程序的解耦合(解耦)或者理解爲降低了程序間的依賴關係,從而提高程序間的獨立性,滿足開閉原則,提高了可複用性和可修改性。可以解釋爲:原始的創建對象的方法都是使用new一個對象,這樣就使得程序間的依賴關係很強,不方便修改和複用,所以我們常常採用工廠方法模式+反射+配置文件來改進,而IOC的底層原理就是使用工廠方法設計模式+反射+XML配置文件或註解來創建對象,只不過原始的創建對象的任務是交給程序員來編寫,而現在使用Spring框架後,創建對象的任務就交給了Spring來管理。

2、關於IOC的一些細節

BeanFactory是Spring的IOC核心容器中的頂層接口,ApplicationContext是BeanFactory的子接口,這兩個接口也是常用的創建bean對象的接口。

兩者的區別:

ApplicationContext:一般是單例對象使用,它在構建核心容器時,創建對象採取的策略是採用立即加載的方式。也就是說,只要一讀取完配置文件馬上就創建配置文件中配置的對象(開發通常採用這個接口)

BeanFactory:一般是多例對象使用,它在構建核心容器時,創建對象採取的策略是採用延遲加載的方式。也就是說,什麼時候根據id獲取對象了,什麼時候才真正的創建對象。

ApplicationContext常用的三個實現類:

ClassPathXmlApplicationContext:加載類路徑下的配置文件,要求配置文件必須在類路徑下。不在的話,加載不了。(常用)

FileSystemXmlApplicationContext:加載磁盤任意路徑下的配置文件(必須有訪問權限)

AnnotationConfigApplicationContext:用於讀取註解創建容器的

3、Spring對bean的管理細節

1)、創建bean對象的三種方式:

第一種方式:使用默認構造函數創建。 在spring的配置文件中使用bean標籤,配以id和class屬性之後,且沒有其他屬性和標籤時。 採用的就是默認構造函數創建bean對象,此時如果類中沒有默認構造函數,則對象無法創建。

eg:<bean id="對象名(accountService)" class="實現類的全限定類名(com.spring.service.impl.AccountServiceImpl)"></bean>

第二種方式: 使用普通工廠中的方法創建對象(使用某個類中的方法創建對象,並存入spring容器)

eg:<bean id="instanceFactory" class="com.spring.factory.InstanceFactory"></bean>

<bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>

第三種方式:使用工廠中的靜態方法創建對象(使用某個類中的靜態方法創建對象,並存入spring容器)

eg:<bean id="accountService" class="com.spring.factory.StaticFactory" factory-method="getAccountService"></bean>

注:上面所給出的id,class,factory-bean,factory-method屬性值要根據自己的項目來寫

2)、bean的作用範圍

bean標籤的scope屬性

作用:用於指定bean的作用範圍

取值: 常用的就是單例的和多例的

singleton:單例的(默認值)一個應用只有一個對象的實例。它的作用範圍就是整個引用。 

prototype:多例的 , 每次訪問對象時,都會重新創建對象實例。

request:作用於web應用的請求範圍,web項目中,Spring 創建一個 Bean 的對象,將對象存入到 request 域中

session:作用於web應用的會話範圍,web項目中,Spring 創建一個 Bean 的對象,將對象存入到 session 域中

global-session:作用於集羣環境的會話範圍(全局會話範圍),當不是集羣環境時,它就是session

eg:<bean id="accountService" class="com.spring.service.impl.AccountServiceImpl" scope="prototype"></bean> -->

3)、bean對象的生命週期

單例對象:scope="singleton"

出生:當容器創建時對象出生

活着:只要容器還在,對象一直活着

死亡:容器銷燬,對象消亡

總結:單例對象的生命週期和容器相同

多例對象:scope="prototype"

出生:當我們使用對象時spring框架爲我們創建

活着:對象只要是在使用過程中就一直活着。

死亡:當對象長時間不用,且沒有別的對象引用時,由Java的垃圾回收器回收

eg:<bean id="accountService" class="com.spring.service.impl.AccountServiceImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>

4、spring 的依賴注入

依賴注入:(Dependency Injection)它是 spring 框架核心 ioc 的具體實現。 我們的程序在編寫時,通過控制反轉,把對象的創建交給了 spring,但是代碼中不可能出現沒有依賴的情況。 ioc 解耦只是降低他們的依賴關係,但不會消除。例如:我們的業務層仍會調用持久層的方法。 那這種業務層和持久層的依賴關係,在使用 spring 之後,就讓 spring 來維護了。 簡單的說,就是坐等框架把持久層(DAO)對象傳入業務層(Service),而不用我們自己去獲取。(再說通俗一點就是“賦值”)

能注入的數據有三類:基本類型和String其他bean類型(在配置文件中或者註解配置過的bean)、複雜類型/集合類型

注入的方式有三種:1)使用構造函數       2)使用set方法    3)使用註解

1)、構造函數的注入:(顧名思義,就是使用類中的構造函數,給成員變量賦值。注意,賦值的操作不是我們自己做的,而是通過配置的方式,讓 spring 框架來爲我們注入)

使用的標籤:constructor-arg

標籤出現的位置:bean標籤的內部

標籤中的屬性

type:用於指定要注入的數據的數據類型,該數據類型也是構造函數中某個或某些參數的類型

index:用於指定要注入的數據給構造函數中指定索引位置的參數賦值。索引的位置是從0開始

name:用於指定給構造函數中指定名稱的參數賦值(常用)

注:以上三個用於指定給構造函數中哪個參數賦值

value:用於提供基本類型和String類型的數據

ref:用於指定其他的bean類型數據。它指的就是在spring的Ioc核心容器中出現過的bean對象

優勢: 在獲取bean對象時,注入數據是必須的操作,否則對象無法創建成功。

弊端: 改變了bean對象的實例化方式,使我們在創建對象時,如果用不到這些數據,也必須提供。

eg:

2)set方法注入(顧名思義,就是在類中提供需要注入成員的 set 方法)   最常用的方式

涉及的標籤:property

出現的位置:bean標籤的內部

標籤的屬性

name:用於指定注入時所調用的set方法名稱

value:用於提供基本類型和String類型的數據

ref:用於指定其他的bean類型數據。它指的就是在spring的Ioc核心容器中出現過的bean對象

優勢: 創建對象時沒有明確的限制,可以直接使用默認構造函數

弊端: 如果有某個成員必須有值,則獲取對象是有可能set方法沒有執行。

eg:數據類型爲基本類型和String其他bean類型時:

數據類型爲複雜類型/集合類型

三、基於註解的 IOC 配置

1、用於創建對象的

XML配置文件中:編寫一個<bean>標籤(如上創建bean對象的三種方式)

註解中:@Component註解 

作用:用於把當前類對象存入spring容器中

屬性:  value:用於指定bean的id。當我們不寫時,它的默認值是當前類名,且首字母改小寫

但在三層架構中spring框架爲我們提供了具體的註解:

表現層:@Controller

業務層:@Service

持久層:@Repository

注:以上三個註解他們的作用和屬性與Component是一模一樣。

2、用於注入數據的

XML配置文件中:如上的三種方式,constructor-arg、property

註解中:

1):@Autowired(無屬性)

作用:自動按照類型注入。只要容器中有唯一的一個bean對象類型和要注入的變量類型匹配,就可以注入成功, 如果ioc容器

沒有任何bean的類型和要注入的變量類型匹配,則報錯(因爲IOC容器是一個Map結構

出現的位置:可以是變量上,也可以是方法上

2):@Qualifier

作用:在按照類中注入的基礎之上再按照名稱注入。它在給類成員注入時不能單獨使用(必須結合@Autowired使用)。但是在給方法參數注入時可以

屬性:value:用於指定注入bean的id 

例如:

3):@Resource

作用:直接按照bean的id注入。它可以獨立使用

屬性:name:用於指定bean的id。

注: 以上三個注入都只能注入其他bean類型的數據,而基本類型和String類型無法使用上述註解實現, 另外,集合類型的注入只能通過XML來實現

4):@Value(可以注入基本類型和String類型的數據)

作用:用於注入基本類型和String類型的數據

屬性: value:用於指定數據的值。它可以使用spring中SpEL(也就是spring的el表達式),SpEL的寫法:${表達式}

3、用於改變作用範圍的

XML配置中:scope屬性

註解中:@Scope

作用:指定bean的作用範圍

屬性:value:指定範圍的取值。常用取值:singleton prototype(如註解一樣)

4、用於改變生命週期的

XML配置中:init-method、destroy-method屬性

註解中:

@PostConstruct:用於指定初始化方法

@PreDestroy:用於指定銷燬方法

 

發佈了16 篇原創文章 · 獲贊 8 · 訪問量 9805
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章