一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 小試牛刀,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Bean容器!

小試牛刀,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Bean容器!

2021-05-21 01:20bugstack蟲洞棧小傅哥 Java教程

整篇關(guān)于 Spring Bean 容器的一個(gè)雛形就已經(jīng)實(shí)現(xiàn)完成了,相對(duì)來(lái)說(shuō)這部分代碼并不會(huì)難住任何人,只要你稍加嘗試就可以接受這部分內(nèi)容的實(shí)現(xiàn)。

 一、前言

 

上學(xué)時(shí),老師總說(shuō):不會(huì)你就問(wèn),但多數(shù)時(shí)候都不知道要問(wèn)什么!

你總會(huì)在小傅哥的文章前言里,發(fā)現(xiàn)一些關(guān)于成長(zhǎng)、學(xué)習(xí)、感悟以及對(duì)當(dāng)篇內(nèi)容的一個(gè)介紹,其實(shí)之所以寫這樣的鋪墊性內(nèi)容,主要是為了讓大家對(duì)接下來(lái)的內(nèi)容學(xué)習(xí)有一個(gè)較輕松的開場(chǎng)和過(guò)度。

就像我們上學(xué)時(shí)如果某一科的內(nèi)容不會(huì)時(shí),老師經(jīng)常會(huì)說(shuō),你有不會(huì)的就要問(wèn)。但對(duì)于學(xué)生本身來(lái)講,可能已經(jīng)不會(huì)的太多了,或者壓根不知道自己不會(huì)什么,只有等看到老師出完的試卷才發(fā)現(xiàn)自己什么都不會(huì)。但要是讓問(wèn),又不知道從哪問(wèn),問(wèn)出蘿卜帶出泥,到處都是知識(shí)漏洞。

所以我希望用一些前置內(nèi)容的鋪墊,讓大家可以在一個(gè)稍有共識(shí)的場(chǎng)景下進(jìn)行學(xué)習(xí),或多或少能為你鋪墊出一個(gè)稍許平緩的接受期。有可能某些時(shí)候也會(huì)打打雞血、刺激刺激學(xué)習(xí)、總歸把知識(shí)學(xué)到手就是好的!

二、目標(biāo)

 

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è)過(guò)程包括 Bean 的初始化、屬性填充等,最終我們就可以完整的使用一個(gè) Bean 實(shí)例化后的對(duì)象了。

而我們本章節(jié)的案例目標(biāo)就是定義一個(gè)簡(jiǎn)單的 Spring 容器,用于定義、存放和獲取 Bean 對(duì)象。

三、設(shè)計(jì)

 

凡是可以存放數(shù)據(jù)的具體數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),都可以稱之為容器。例如:ArrayList、LinkedList、HashSet等,但在 Spring Bean 容器的場(chǎng)景下,我們需要一種可以用于存放和名稱索引式的數(shù)據(jù)結(jié)構(gòu),所以選擇 HashMap 是最合適不過(guò)的。

這里簡(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ù)較多的情況。不過(guò)我們經(jīng)過(guò)10萬(wàn)數(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ì)如下;

小試牛刀,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Bean容器!

定義:BeanDefinition,可能這是你在查閱 Spring 源碼時(shí)經(jīng)常看到的一個(gè)類,例如它會(huì)包括 singleton、prototype、BeanClassName 等。但目前我們初步實(shí)現(xiàn)會(huì)更加簡(jiǎn)單的處理,只定義一個(gè) Object 類型用于存放對(duì)象。

注冊(cè):這個(gè)過(guò)程就相當(dāng)于我們把數(shù)據(jù)存放到 HashMap 中,只不過(guò)現(xiàn)在 HashMap 存放的是定義了的 Bean 的對(duì)象信息。

獲取:最后就是獲取對(duì)象,Bean 的名字就是key,Spring 容器初始化好 Bean 以后,就可以直接獲取了。

接下來(lái)我們就按照這個(gè)設(shè)計(jì),做一個(gè)簡(jiǎn)單的 Spring Bean 容器代碼實(shí)現(xiàn)。編碼的過(guò)程往往并不會(huì)有多復(fù)雜,但知曉設(shè)計(jì)過(guò)程卻更加重要!

四、實(shí)現(xiàn)

 

1. 工程結(jié)構(gòu)

  1. small-spring-step-01 
  2. └── src 
  3.     ├── main 
  4.     │   └── java 
  5.     │       └── cn.bugstack.springframework 
  6.     │           ├── BeanDefinition.java 
  7.     │           └── BeanFactory.java 
  8.     └── test 
  9.         └── java 
  10.             └── cn.bugstack.springframework.test   
  11.                 ├── bean 
  12.                 │   └── UserService.java                 
  13.                 └── ApiTest.java 

工程源碼:https://github.com/small-spring/small-spring-step-01 (公眾號(hào):bugstack蟲洞棧,回復(fù):Spring 專欄,獲取整套源碼)

Spring Bean 容器類關(guān)系,如圖 2-2

小試牛刀,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Bean容器!

圖 2-2

  • Spring Bean 容器的整個(gè)實(shí)現(xiàn)內(nèi)容非常簡(jiǎn)單,也僅僅是包括了一個(gè)簡(jiǎn)單的 BeanFactory 和 BeanDefinition,這里的類名稱是與 Spring 源碼中一致,只不過(guò)現(xiàn)在的類實(shí)現(xiàn)會(huì)相對(duì)來(lái)說(shuō)更簡(jiǎn)化一些,在后續(xù)的實(shí)現(xiàn)過(guò)程中再不斷的添加內(nèi)容。
  • BeanDefinition,用于定義 Bean 實(shí)例化信息,現(xiàn)在的實(shí)現(xiàn)是以一個(gè) Object 存放對(duì)象

BeanFactory,代表了 Bean 對(duì)象的工廠,可以存放 Bean 定義到 Map 中以及獲取。

2. Bean 定義

  1. public class BeanDefinition { 
  2.  
  3.     private Object bean; 
  4.  
  5.     public BeanDefinition(Object bean) { 
  6.         this.bean = bean; 
  7.     } 
  8.  
  9.     public Object getBean() { 
  10.         return bean; 
  11.     } 
  12.  
  • 目前的 Bean 定義中,只有一個(gè) Object 用于存放 Bean 對(duì)象。如果感興趣可以參考 Spring 源碼中這個(gè)類的信息,名稱都是一樣的。
  • 不過(guò)在后面陸續(xù)的實(shí)現(xiàn)中會(huì)逐步完善 BeanDefinition 相關(guān)屬性的填充,例如:SCOPE_SINGLETON、SCOPE_PROTOTYPE、ROLE_APPLICATION、ROLE_SUPPORT、ROLE_INFRASTRUCTURE 以及 Bean Class 信息。

3. Bean 工廠

  1. public class BeanFactory { 
  2.  
  3.     private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); 
  4.  
  5.     public Object getBean(String name) { 
  6.         return beanDefinitionMap.get(name).getBean(); 
  7.     } 
  8.  
  9.     public void registerBeanDefinition(String name, BeanDefinition beanDefinition) { 
  10.         beanDefinitionMap.put(name, beanDefinition); 
  11.     } 
  12.  

在 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é)果,只不過(guò)實(shí)現(xiàn)過(guò)程只展示出基本的核心原理。在后續(xù)的補(bǔ)充實(shí)現(xiàn)中,這個(gè)會(huì)不斷變得龐大。

五、測(cè)試

 

1. 事先準(zhǔn)備

  1. public class UserService { 
  2.  
  3.     public void queryUserInfo(){ 
  4.         System.out.println("查詢用戶信息"); 
  5.     } 
  6.  

這里簡(jiǎn)單定義了一個(gè) UserService 對(duì)象,方便我們后續(xù)對(duì) Spring 容器測(cè)試。

2. 測(cè)試用例

  1. @Test 
  2. public void test_BeanFactory(){ 
  3.     // 1.初始化 BeanFactory 
  4.     BeanFactory beanFactory = new BeanFactory(); 
  5.      
  6.     // 2.注冊(cè) bean 
  7.     BeanDefinition beanDefinition = new BeanDefinition(new UserService()); 
  8.     beanFactory.registerBeanDefinition("userService", beanDefinition); 
  9.      
  10.     // 3.獲取 bean 
  11.     UserService userService = (UserService) beanFactory.getBean("userService"); 
  12.     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é)果

  1. 查詢用戶信息 
  2.  
  3. Process finished with exit code 0 

通過(guò)測(cè)試結(jié)果可以看到,目前的 Spring Bean 容器案例,已經(jīng)稍有雛形。

六、總結(jié)

 

  • 整篇關(guān)于 Spring Bean 容器的一個(gè)雛形就已經(jīng)實(shí)現(xiàn)完成了,相對(duì)來(lái)說(shuō)這部分代碼并不會(huì)難住任何人,只要你稍加嘗試就可以接受這部分內(nèi)容的實(shí)現(xiàn)。
  • 但對(duì)于一個(gè)知識(shí)的學(xué)習(xí)來(lái)說(shuō),寫代碼只是最后的步驟,往往整個(gè)思路、設(shè)計(jì)、方案,才更重要,只要你知道了因?yàn)槭裁础⑺允裁矗拍茏屇阌幸粋€(gè)真正的理解。
  • 下一章節(jié)會(huì)在此工程基礎(chǔ)上擴(kuò)容實(shí)現(xiàn),要比現(xiàn)在的類多一些。不過(guò)每一篇的實(shí)現(xiàn)上,我都會(huì)以一個(gè)需求視角進(jìn)行目標(biāo)分析和方案設(shè)計(jì),讓大家在學(xué)習(xí)編碼之外更能注重更多技術(shù)價(jià)值的學(xué)習(xí)。

原文鏈接:https://mp.weixin.qq.com/s/1W-e6xfOfrKwKm32TRFQZQ

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 校园纯肉H教室第一次 | 女同志 videos| 男人机机桶女人机机 | luan小说| 国产精品免费aⅴ片在线观看 | 久久九九久精品国产尤物 | 国产成人精品视频一区二区不卡 | 日本-区二区三区免费精品 日本破处 | 草嫩社区| 国产高清不卡视频在线播放 | 星星动漫在线观看无删减 | 国产色视频一区二区三区 | 国产精品久久久久jk制服 | 成人免费国产欧美日韩你懂的 | 亚洲国产天堂在线观看 | 好深快点再快点好爽视频 | 92国产福利久久青青草原 | 国产永久免费爽视频在线 | 四虎 2022 永久网站 | 国产大片51精品免费观看 | a级情欲片在线观看hd | 2020国语对白露脸 | 羞羞色男人的天堂伊人久久 | 日韩特级片 | 国产精品国语自产拍在线观看 | 精品国产自在现线拍400部 | 天天天天天干 | 高清黄色直接看 | 暖暖视频免费观看视频中国.韩剧 | 日韩日b视频 | 国产成人精品视频一区二区不卡 | 国产精品日本亚洲777 | 日本老妇和子乱视频 | 91精品国产综合久久精品 | 好大好深视频 | 我把校花黑色蕾丝胸罩脱了 | 国内会所按摩推拿国产 | 特黄特级高清免费视频毛片 | 国产麻豆剧果冻传媒影视4934 | 亚洲国产婷婷俺也色综合 | 十大免费批日的软件 |