在學習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...