實(shí)現(xiàn)Bean容器的示例分析,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
創(chuàng)新互聯(lián)是專業(yè)的古縣網(wǎng)站建設(shè)公司,古縣接單;提供網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行古縣網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
一、Spring Bean 容器是什么?
Spring 包含并管理應(yīng)用對(duì)象的配置和生命周期,在這個(gè)意義上它是一種用于承載對(duì)象的容器,你可以配置你的每個(gè) Bean 對(duì)象是如何被創(chuàng)建的,這些 Bean 可以創(chuàng)建一個(gè)單獨(dú)的實(shí)例或者每次需要時(shí)都生成一個(gè)新的實(shí)例,以及它們是如何相互關(guān)聯(lián)構(gòu)建和使用的。
如果一個(gè) Bean 對(duì)象交給 Spring 容器管理,那么這個(gè) Bean 對(duì)象就應(yīng)該以類似零件的方式被拆解后存放到 Bean 的定義中,這樣相當(dāng)于一種把對(duì)象解耦的操作,可以由 Spring 更加容易的管理,就像處理循環(huán)依賴等操作。
當(dāng)一個(gè) Bean 對(duì)象被定義存放以后,再由 Spring 統(tǒng)一進(jìn)行裝配,這個(gè)過程包括 Bean 的初始化、屬性填充等,最終我們就可以完整的使用一個(gè) Bean 實(shí)例化后的對(duì)象了。
而我們本章節(jié)的案例目標(biāo)就是定義一個(gè)簡(jiǎn)單的 Spring 容器,用于定義、存放和獲取 Bean 對(duì)象。
凡是可以存放數(shù)據(jù)的具體數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),都可以稱之為容器。例如:ArrayList、LinkedList、HashSet等,但在 Spring Bean 容器的場(chǎng)景下,我們需要一種可以用于存放和名稱索引式的數(shù)據(jù)結(jié)構(gòu),所以選擇 HashMap 是最合適不過的。
這里簡(jiǎn)單介紹一下 HashMap,HashMap 是一種基于擾動(dòng)函數(shù)、負(fù)載因子、紅黑樹轉(zhuǎn)換等技術(shù)內(nèi)容,形成的拉鏈尋址的數(shù)據(jù)結(jié)構(gòu),它能讓數(shù)據(jù)更加散列的分布在哈希桶以及碰撞時(shí)形成的鏈表和紅黑樹上。它的數(shù)據(jù)結(jié)構(gòu)會(huì)盡可能最大限度的讓整個(gè)數(shù)據(jù)讀取的復(fù)雜度在 O(1) ~ O(Logn) ~O(n)之間,當(dāng)然在極端情況下也會(huì)有 O(n) 鏈表查找數(shù)據(jù)較多的情況。不過我們經(jīng)過10萬數(shù)據(jù)的擾動(dòng)函數(shù)再尋址驗(yàn)證測(cè)試,數(shù)據(jù)會(huì)均勻的散列在各個(gè)哈希桶索引上,所以 HashMap 非常適合用在 Spring Bean 的容器實(shí)現(xiàn)上。
另外一個(gè)簡(jiǎn)單的 Spring Bean 容器實(shí)現(xiàn),還需 Bean 的定義、注冊(cè)、獲取三個(gè)基本步驟,簡(jiǎn)化設(shè)計(jì)如下;
定義:BeanDefinition,可能這是你在查閱 Spring 源碼時(shí)經(jīng)??吹降囊粋€(gè)類,例如它會(huì)包括 singleton、prototype、BeanClassName 等。但目前我們初步實(shí)現(xiàn)會(huì)更加簡(jiǎn)單的處理,只定義一個(gè) Object 類型用于存放對(duì)象。
注冊(cè):這個(gè)過程就相當(dāng)于我們把數(shù)據(jù)存放到 HashMap 中,只不過現(xiàn)在 HashMap 存放的是定義了的 Bean 的對(duì)象信息。
獲?。鹤詈缶褪谦@取對(duì)象,Bean 的名字就是key,Spring 容器初始化好 Bean 以后,就可以直接獲取了。
接下來我們就按照這個(gè)設(shè)計(jì),做一個(gè)簡(jiǎn)單的 Spring Bean 容器代碼實(shí)現(xiàn)。編碼的過程往往并不會(huì)有多復(fù)雜,但知曉設(shè)計(jì)過程卻更加重要!
1. 工程結(jié)構(gòu)
small-spring-step-01 └── src ├── main │ └── java │ └── cn.bugstack.springframework │ ├── BeanDefinition.java │ └── BeanFactory.java └── test └── java └── cn.bugstack.springframework.test ├── bean │ └── UserService.java └── ApiTest.java
工程源碼:https://github.com/small-spring/small-spring-step-01 (公眾號(hào):bugstack蟲洞棧,回復(fù):Spring 專欄,獲取整套源碼)
Spring Bean 容器類關(guān)系,如圖 2-2
圖 2-2
Spring Bean 容器的整個(gè)實(shí)現(xiàn)內(nèi)容非常簡(jiǎn)單,也僅僅是包括了一個(gè)簡(jiǎn)單的 BeanFactory 和 BeanDefinition,這里的類名稱是與 Spring 源碼中一致,只不過現(xiàn)在的類實(shí)現(xiàn)會(huì)相對(duì)來說更簡(jiǎn)化一些,在后續(xù)的實(shí)現(xiàn)過程中再不斷的添加內(nèi)容。
BeanDefinition,用于定義 Bean 實(shí)例化信息,現(xiàn)在的實(shí)現(xiàn)是以一個(gè) Object 存放對(duì)象
BeanFactory,代表了 Bean 對(duì)象的工廠,可以存放 Bean 定義到 Map 中以及獲取。
2. Bean 定義
public class BeanDefinition { private Object bean; public BeanDefinition(Object bean) { this.bean = bean; } public Object getBean() { return bean; } }
目前的 Bean 定義中,只有一個(gè) Object 用于存放 Bean 對(duì)象。如果感興趣可以參考 Spring 源碼中這個(gè)類的信息,名稱都是一樣的。
不過在后面陸續(xù)的實(shí)現(xiàn)中會(huì)逐步完善 BeanDefinition 相關(guān)屬性的填充,例如:SCOPE_SINGLETON、SCOPE_PROTOTYPE、ROLE_APPLICATION、ROLE_SUPPORT、ROLE_INFRASTRUCTURE 以及 Bean Class 信息。
3. Bean 工廠
public class BeanFactory { private MapbeanDefinitionMap = new ConcurrentHashMap<>(); public Object getBean(String name) { return beanDefinitionMap.get(name).getBean(); } public void registerBeanDefinition(String name, BeanDefinition beanDefinition) { beanDefinitionMap.put(name, beanDefinition); } }
在 Bean 工廠的實(shí)現(xiàn)中,包括了 Bean 的注冊(cè),這里注冊(cè)的是 Bean 的定義信息。同時(shí)在這個(gè)類中還包括了獲取 Bean 的操作。
目前的 BeanFactory 仍然是非常簡(jiǎn)化的實(shí)現(xiàn),但這種簡(jiǎn)化的實(shí)現(xiàn)內(nèi)容也是整個(gè) Spring 容器中關(guān)于 Bean 使用的最終體現(xiàn)結(jié)果,只不過實(shí)現(xiàn)過程只展示出基本的核心原理。在后續(xù)的補(bǔ)充實(shí)現(xiàn)中,這個(gè)會(huì)不斷變得龐大。
1. 事先準(zhǔn)備
public class UserService { public void queryUserInfo(){ System.out.println("查詢用戶信息"); } }
這里簡(jiǎn)單定義了一個(gè) UserService 對(duì)象,方便我們后續(xù)對(duì) Spring 容器測(cè)試。
2. 測(cè)試用例
@Test public void test_BeanFactory(){ // 1.初始化 BeanFactory BeanFactory beanFactory = new BeanFactory(); // 2.注冊(cè) bean BeanDefinition beanDefinition = new BeanDefinition(new UserService()); beanFactory.registerBeanDefinition("userService", beanDefinition); // 3.獲取 bean UserService userService = (UserService) beanFactory.getBean("userService"); userService.queryUserInfo(); }
在單測(cè)中主要包括初始化 Bean 工廠、注冊(cè) Bean、獲取 Bean,三個(gè)步驟,使用效果上貼近與 Spring,但顯得會(huì)更簡(jiǎn)化。
在 Bean 的注冊(cè)中,這里是直接把 UserService 實(shí)例化后作為入?yún)鬟f給 BeanDefinition 的,在后續(xù)的陸續(xù)實(shí)現(xiàn)中,我們會(huì)把這部分內(nèi)容放入 Bean 工廠中實(shí)現(xiàn)。
3. 測(cè)試結(jié)果
查詢用戶信息 Process finished with exit code 0
通過測(cè)試結(jié)果可以看到,目前的 Spring Bean 容器案例,已經(jīng)稍有雛形。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。