摘要:有多種注入的策略,比如按照裝配名稱,或者是默認實現了接口或者抽象類的子類實例對象來注入。這個方法中,做了一些簡單的判斷,如果這個類本身就不是一個抽象類或者不是一個接口,那么這個類就是第一個合適的類。
申明:本文不是講解Spring如何使用注解,本文只是通過一個簡單的實現,來理解Spring是如何注入一個對象的。
??用過Spring的同學都知道,Spring利用注解來實現依賴注入,使得各個類之間的耦合性極大的降低了。但是僅僅是使用,并不能理解到Spring內部是怎么實現的。筆者沒有看過Spring的源碼。只能從自己的角度來談談Spring是怎么實現的。感興趣的同學可以在看過本文之后,深入的了解Spring.
??很多時候,我們都有這樣的應用場景。比如DAO層,你會先申明一個接口,比如IUserDao,表示用來處理User的一個接口,然后再寫一個實現類UserDaoImpl實現了IUserDao中的方法,然后在上層service層中注入。啟動之后Spring將自己掃描自動為我們注入實例化的對象,使得我們不用在意各個對象的生命周期。接下來就來聊聊具體是怎么注入的。
假設現在已經有以下的類:
public interface IUserDao { public void setData(String data); public String getData(); } public class UserDaoImpl implements IUserDao{ @Override public void setData(String data) { System.out.println("data is : " + data); } @Override public String getData() { return "just test"; } }
??其中FieldInject是筆者模仿寫的一個注解,具體定義如下
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface FieldInject { //假設有一些變量用于控制策略 }
??具體關于注解上面的元注解的含義,可以看另外一篇博客。這里就不展開說明了。
以上就是準備工作了,接下來就是講解真正的初始化方法了。
??假設我們現在有一個類的Class對象,那么我們可以根據這個Class對象找到哪些成員變量是加了指定的注解的。代碼如下
//下面開始注入 for(int i=0; i??在這段代碼中,筆者查詢的注解是自己實現的一個FieldInject注解,注解本身并不影響代碼的執行。通過判斷是否為空可以得出某個成員變量是否加了指定的注解。如果發現成員變量加了注解,就可以為該成員變量注入實例化的對象了。
??問題1:怎么知道注入哪個對象?
??問題2:怎么注入?
??問題2很好解決,如果原來的類中帶有setter方法,那么可以使用method.invoke()方法來調用并注入。或者通過field直接注入都可以。那么主要是問題1,怎么找到合適的注入對象。
??Spring有多種注入的策略,比如按照裝配名稱,或者是默認實現了接口或者抽象類的子類實例對象來注入。總之,不同的策略只是選擇的不同,我們可以假定使用找到的第一個合適子類的實例對象來注入。//找到某個類的子類【涉及到Spring的選擇策略】 private Class findSubClass(String fullClassName){ try { Class target = Class.forName(fullClassName); //不是抽象類,不是接口,那自身就好了。 if(!target.isInterface()){ boolean isAbs = Modifier.isAbstract(target.getModifiers()); if(!isAbs) return target; } int size = clazzList.size(); for(int i=0; i??findSubClass是用來找到某個類的合適子類,類似于Spring中根據某種策略來查找,這里使用了比較簡單的方法。找到第一個合適的子類即可。這個方法中,做了一些簡單的判斷,如果這個類本身就不是一個抽象類或者不是一個接口,那么這個類就是第一個合適的類。如果這個類是一個接口或者一個抽象類,那么就在全局掃描的classList中找到合適的類。找到合適的類之后,下一步就是一個注入了,筆者采用的是給setter方法注入,如果想直接給成員變量賦值也是非常簡單的。只要替換掉方法injectMethod,換成下面兩句代碼即可。
field[i].setAccessible(true); field[i].set(target, obj);??injectMethod實現也是比較簡單,通過比對Method中的方法,找到合適的setter方法(這里是通過field的名稱來判斷的),并將實例對象賦值進去即可。以上就是一個簡單的注入過程的實現。筆者寫的比較匆忙,可能有些細節上經不起推敲。但是如果能為迷惑的初學者提供一個思路也是不錯的,這份代碼我都上傳到github上了,如果想下載進行運行的可以移步我的github。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66788.html
摘要:使用的好處知乎的回答不用自己組裝,拿來就用。統一配置,便于修改。 前言 只有光頭才能變強 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡單啦 單例模式你會幾種寫法? 工廠模式理解了沒有? 在刷Spring書籍的時候花了點時間去學習了單例模式和工廠模式,總的來說還是非常值得的! 本來想的是刷完《Spring 實戰 (第4版)》和《精通Spring4.x 企業應用開發實戰》...
摘要:它的構造器上添加了注解,這表明當創建的時候,會通過這個構造器來進行實例化并且會傳入一個可設置給類型的通過自動裝配,將一個注入到之中注解不僅能夠用在構造器上,還能用在屬性的方法上。 Spring配置的可選方案 Spring容器負責創建應用程序中的bean并通過DI來協調這些對象之間的關系。當描述bean如何進行裝配時,Spring具有非常大的靈活性,它提供了三種主要的裝配機制: 在XM...
摘要:關于依賴注入注入的注解提供的注解不僅僅是對象,還有在構造器上,還能用在屬性的方法上。與之相反,的限定符能夠在所有可選的上進行縮小范圍的操作,最終能夠達到只有一個滿足所規定的限制條件。注解是使用限定符的主要方式。 本文首發于泊浮目的專欄:https://segmentfault.com/blog... Spring致力于提供一種方法管理你的業務對象。在大量Java EE的應用中,隨處可...
摘要:入門篇學習總結時間年月日星期三說明本文部分內容均來自慕課網。主要的功能是日志記錄,性能統計,安全控制,事務處理,異常處理等等。 《Spring入門篇》學習總結 時間:2017年1月18日星期三說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://git...
摘要:先來看代碼吧,一會松哥再慢慢解釋關于這一段自動配置,解釋如下首先注解表明這是一個配置類。本文的案例,松哥已經上傳到上了,地址。我們使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 為我們帶來了眾多的自動化配置,有了這些自動化配置,我們可以不費吹灰之力就能搭建一個生產級開發環境,有的小伙伴會覺得這個 Starter 好神奇呀!其實 Starter 也都...
閱讀 3115·2023-04-25 15:02
閱讀 2806·2021-11-23 09:51
閱讀 2030·2021-09-27 13:47
閱讀 1984·2021-09-13 10:33
閱讀 957·2019-08-30 15:54
閱讀 2640·2019-08-30 15:53
閱讀 2853·2019-08-29 13:58
閱讀 881·2019-08-29 13:54