實現簡單的Spring容器

2021-10-01 02:28:43 字數 4427 閱讀 5949

在學習spring的時候,常聽到的兩個東西:ioc和di。

ioc:控制反轉,將物件的生命週期交給spring去維護,我們需要物件時從容器中拿。

di:依賴注入,類與類之間的依賴關係也交給spring去維護。例如:a依賴b,程式執行時spring會幫我們自動注入b例項。

檢視spring的原始碼會非常頭疼,spring封裝了太多的類,設計固然優秀,但是小白看起來確實很吃力啊…

今天通過註解的方式來實現。

實現前先簡單分析一下過程,沒有思路是很難寫**的。

先總結一下需要用到的註解。

基本註解

學過spring肯定對這些註解很熟悉,現在我們要自己來實現這些註解。

為了區別於spring的註解,自定義註解都會加「my」字首。

實現過程

編寫自己的註解

定義需要掃瞄的包路徑

將掃瞄的類進行例項化,放到容器中

將例項化的類進行加工(依賴注入)

客戶端獲取bean時從容器中返回

首先定義需要用到的4個基本註解,然後再來實現功能。

@target

(elementtype.type)

@documented

@retention

(retentionpolicy.runtime)

//元件類的掃瞄

public @inte***ce

mycommentscan

@target

(elementtype.type)

@documented

@retention

(retentionpolicy.runtime)

//元件 掃瞄到會例項化到容器中

public @inte***ce

mycomment

@target

(elementtype.type)

@documented

@retention

(retentionpolicy.runtime)

//作用域 單例/多例

public @inte***ce

myscope

@target

(elementtype.field)

@documented

@retention

(retentionpolicy.runtime)

//依賴注入

public @inte***ce

myautowrite

/**

* @description: 掃瞄com.ch.entity包下的類

*/@mycommentscan

("com.ch.entity"

)public

class

beanconfig

建立兩個實體類person和wife,且person依賴wife。

將其註冊為元件,註冊到容器中,容器會幫我們自動做 依賴注入。

/**

* @description:

*/@mycomment

//預設單例,可配置

//@myscope("prototype")

@getter

@setter

public

class

person

}@mycomment

@getter

@setter

public

class

wife

}

現在開始編寫核心實現。

beandefinition

編寫乙個類,作用是對bean進行定義描述。

這裡簡單點,只描述 作用域。

/**

* @description: bean的定義描述類

*/@data

public

class

beandefinition

}

這裡實現了所有的邏輯,包括對類進行掃瞄,註冊到容器,對類進行依賴注入等…。

/**

* @description: 基於註解的 應用上下文

*/public

class

private

void

init()

string basepackage = configclassannotation.

value()

;if(strutil.

isblank

(basepackage)

) set

?>> scanclass = classscaner.

scanpackage

(basepackage)

; beancontainer =

newhashmap

<

>(16

);beandefinitionmap =

newhashmap

<

>(16

);for(class<

?> c : scanclass)

try}

catch

(exception e)

}//對bean進行加工

for(map.entry

entry : beancontainer.

entryset()

)}/** * 解析bean的定義

* @param c

*/private

void

resolvebeandefinition

(class c

)/**

* 對bean進行加工 依賴注入

* @param c

* @return

*/private

void

beanprocess

(class c

,object o)

//去容器中找 是否有其依賴的物件if(

!beancontainer.

containskey

(field.

gettype()

))object depend = beancontainer.

get(field.

gettype()

);field.

setaccessible

(true);

trycatch

(illegalacces***ception e)}}

/** * 從容器中獲取物件

* @param c

* @param * @return

*/public

t getbean

(class

c)if

(beandefinition.

issingle()

)if(beandefinition.

isprototype()

)catch

(exception e)

}return null;

}}

單例

容器初始化時直接例項化物件並註冊到容器中,每次獲取時,直接從容器中返回,單例項。

public

class

client

}輸出:

com.ch.entity.person@87aac27

com.ch.entity.person@87aac27

可以看到,獲取的都是同乙個例項。

預設是單例,給person類加上註解:@myscope(「prototype」) 即可。

給person類加上@myscope(「prototype」)註解後重新測試,

輸出如下:

com.ch.entity.person@3e3abc88

com.ch.entity.person@6ce253f1

每次getbean()獲取的都是新的例項。

依賴注入

測試容器是否會幫我們自動注入依賴。

public

class

client

}輸出:

com.ch.entity.person@3e3abc88

person...

com.ch.entity.wife@6ce253f1

wife.

..

可以看到,容器自動幫我們給person例項自動注入了wife例項。

這應該是乙個最簡單的容器了,只實現了最基礎的容器功能,但重要的是明白它的原理不是嘛。

畢竟,人生就是乙個不斷追求「不惑」的過程。

簡單實現spring中Ioc容器

spring的ioc容器是通過工廠模式 反射機制完成的。簡單來說反射機制就是我們可以通過類的名字來生成物件。比如比較常見的用法 person p person class.forname chinese newinstance 這樣子,我們可以直接通過chinese這個類的名字來構造這個物件。下面我...

spring 2 spring容器的實現過程

繼承體系1 defaultresourcereader 轉化為路徑解析器 resourcepatternresolver 2 configlocation 通過resourcepatternresolver轉化為recource resource 3 構建註冊器defaultlistablebean...

Spring之IOC容器的實現

控制反 依賴物件的獲得被反轉了,即依賴注入。beandefinition用來管理基於spring的應用中的各種物件以及它們之間的相互依賴關係。抽象了我們對bean的定義,是讓容器起作用的主要資料模型。依賴反轉功能都是圍繞對beandefinition的處理來完成的。程式設計式使用ioc容器的過程 c...