徒手擼乙個簡單的IOC

2021-09-10 05:42:32 字數 3796 閱讀 9985

spring框架中最經典的兩個就是ioc和aop,其中ioc(inversion of control)是什麼呢?控制反轉,簡單來說就是將控制實體bean的動作交給了spring容器進行管理。再簡單點來說就是例如之前想用乙個類,必須new乙個,但是使用了spring那麼直接用@autowired註解或者用xml配置的方式就能直接獲得此物件,而且你也不用管它的生命週期啊等等之類的。就不用自己new乙個物件了。

如果是之前沒有使用ioc的話,那麼這些物件的建立以及賦值都是由我們自己建立了,下面簡單的演示了如果有上面四個物件依賴的話,那麼沒有ioc我們必須要建立物件並且賦值。僅僅四個物件就這麼多,那麼一旦專案大了,物件成百上千,如果還這樣寫的話,那麼絕對是一場災難。

物件a a = new 物件a();

物件b b = new 物件b();

物件c c = new 物件c();

物件d d = new 物件d();

a.setb(b);

a.setc(c);

b.setd(d);

c.setd(d);

因此在spring中通過ioc將所有的物件統一放到spring的容器中進行管理,所以就簡單了很多。上面的例項化物件的**也不需要我們寫了。

上面說了那麼多,其實就是一句話ioc非常重要,但是如果直接看spring原始碼的話會非常懵逼,所以就簡單的寫乙個ioc的小例子來理解這種思想。

還是編寫**前的分析階段,spring的ioc其實就是將所有的bean放在統一容器中進行管理起來,然後在在獲取的時候進行初始化,所以需要我們在程式啟動的時候將被標記的類進行儲存在自定義的容器中管理。

現在我們就以上面兩個步驟進行詳細點的分析

首先初始化階段我們要先建立兩個註解類用於類的發現(@myioc類似於@service)。

@target(elementtype.type)

@retention(retentionpolicy.runtime)

public @inte***ce myioc

然後要初始化資訊進自定義容器的話用什麼型別的容器去儲存這些資訊呢?這裡可以想到是用map來存,用key為類名,value用什麼呢?value就是要放在容器中進行管理的類的資訊了,那麼乙個類有什麼資訊呢即類是由什麼組成呢?有以下幾個資訊

所以根據上面的分析我們可以建立乙個實體類來儲存這些資訊,此時我們就不考慮複雜的建構函式了,就都是初始化的無參建構函式。然後父類的屬性就不進行分析注入了。所以此時類實體類就簡單了。

@data

public class beandefinition

有了儲存類資訊的類了,那麼我們在程式啟動的時候就應該將這些資訊給載入到map中,此時建立乙個啟動類用於初始化被@myioc標記的類的資訊。

@component

@order(value = 1)

public class iocinitconifg implements commandlinerunner

mybeanfactoryimpl.setbeandinemap(concurrenthashmap);

}private string getclassname(string beanclassname)

}

此時得說一下自定義的統一容器管理的類mybeanfactory此類用作統一獲得類的途徑

public inte***ce mybeanfactory
此時還有其實現類

@log4j

public class mybeanfactoryimpl implements mybeanfactory

//沒有的話就例項化乙個物件

object = getobject(beandefinemap.get(name));

if (object != null)

return object;

}public void setfild(object bean) throws exception }}

public object getobject(beandefinition beandefinition) throws exception catch (classnotfoundexception e)

return clazz;

}public static void setbeandinemap(concurrenthashmapbeandefinemap)

public static void setbeannameset(setbeannameset)

}

此時初始化的階段已經完成了,即已經將所有被@myioc標記的類已經被全部存放在了自定義的容器中了。其實在這裡我們已經能使用自己的自定義的容器進行獲得bean了。

@myioc

@data

public class user

@myioc

public class student

}

此時我們在啟動類中寫如下

user user1 = (user)beanfactory.getbeanbyname("com.example.ioc.domain.user");

user user2 = (user)beanfactory.getbeanbyname("com.example.ioc.domain.user");

student student1 = user1.getstudent();

student student2 = user1.getstudent();

student student3 = (student)beanfactory.getbeanbyname("com.example.ioc.domain.student");

system.out.println(user1);

system.out.println(user2);

system.out.println(student1);

system.out.println(student2);

system.out.println(student3);

發現控制台中輸出的物件都是同乙個物件,並且在user中也自動注入了student物件。此時乙個簡單的ioc就完成了。

user(student=com.example.ioc.domain.student@705e7b93)

user(student=com.example.ioc.domain.student@705e7b93)

com.example.ioc.domain.student@705e7b93

com.example.ioc.domain.student@705e7b93

com.example.ioc.domain.student@705e7b93

本來一開始的想法的是想要寫乙個類似於@autowired註解的自定義註解,但是在編碼過程中遇到了乙個困難,就是例如下面的**,例項化b容易,但是如何將b注入到每乙個例項化的a中,這個問題困擾了我好幾天,也查詢了許多的資料,至今還是沒有解決,估計是只有研究spring原始碼才能夠了解是如何做到的。

@myioc

public class a

從零開始徒手擼乙個vue的toast彈窗元件

相信普通的vue元件大家都會寫,定義 引入 註冊 使用,行雲流水,一氣呵成,但是如果我們今天是要自定義乙個彈窗元件呢?首先,我們來分析一下彈窗元件的特性 需求 0.輕量 乙個元件小於 1kib 實際打包完不到0.8k 1.一般都是多處使用 需要解決每個頁面重複引用 註冊 2.一般都是跟js互動的 無...

純手擼乙個rnn

原文 import copy,numpy as np np.random.seed 0 sigmoid函式 def sigmoid x output 1 1 np.exp x return output sigmoid導數 def sigmoid output to derivative outpu...

從頭擼乙個單鏈表

醉裡挑燈看劍,夢回吹角連營 最近在學習單鏈表時,對於單鏈表的頭節點指標的建立,以及如何給乙個鍊錶存入資料,這塊理解不是很到位。雖然明白鍊錶的基本操作,建立 插入 刪除 索引,但用 實現還是遇到一些問題難以理解,故寫一些 進行分析,終於弄清楚其實現過程,在此作一小結。插入新的節點 刪除節點分析 實現 ...