亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

200行Java代碼如何實(shí)現(xiàn)依賴注入框架詳解

 更新時(shí)間:2018年05月03日 09:27:35   作者:老錢  
依賴注入對(duì)大家來(lái)說(shuō)應(yīng)該都不陌生,下面這篇文章主要給大家介紹了關(guān)于利用200行Java代碼如何實(shí)現(xiàn)依賴注入框架的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

依賴注入介紹

先回顧下依賴注入的概念:

我們常提起的依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念。具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí),在 傳統(tǒng)的程序設(shè)計(jì)過(guò)程中,通常由調(diào)用者來(lái)創(chuàng)建被調(diào)用者的實(shí)例。但在Spring里,創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來(lái)完成,因此稱為控制反轉(zhuǎn);創(chuàng)建被調(diào)用者 實(shí)例的工作通常由Spring容器來(lái)完成,然后注入調(diào)用者,因此也稱為依賴注入。

其實(shí)簡(jiǎn)單的說(shuō),依賴注入起到的作用就是講對(duì)象之間的依賴關(guān)系從原先的代碼中解耦出來(lái),通過(guò)配置文件或注解等方式加上Spring框架的處理讓我們對(duì)依賴關(guān)系靈活集中的進(jìn)行管理。

依賴注入框架

依賴注入框架并不神秘,其實(shí)它是非常簡(jiǎn)單的東西。不要去看spring的依賴注入源碼,因?yàn)槟阒灰蝗タ淳鸵馕吨阍僖矊懖桓蚁率肿约簲]了,它的功能因?yàn)檫^(guò)于強(qiáng)大,所以設(shè)計(jì)也過(guò)于復(fù)雜,普通程序員一眼看去只能望洋興嘆。

我也并沒(méi)有去細(xì)致閱讀spring源碼。即便如此也只用了半天的時(shí)間便自己擼了一個(gè)基本滿足標(biāo)準(zhǔn)依賴注入規(guī)范「JSR-330」的小框架iockids。這個(gè)小框架只有一個(gè)主類Injector,大約200行代碼,它具備以下功能。

  1. 單例/非單例注入
  2. 構(gòu)造器注入
  3. 字段注入
  4. 循環(huán)依賴注入
  5. Qualifier注入

我們看一個(gè)稍微復(fù)雜一點(diǎn)的使用示例

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import iockids.Injector;
@Singleton
class Root {
 @Inject
 @Named("a")
 Node a;
 @Inject
 @Named("b")
 Node b;
 @Override
 public String toString() {
  return String.format("root(%s, %s)", a.name(), b.name());
 }
}

interface Node {
 String name();
}

@Singleton
@Named("a")
class NodeA implements Node {
 @Inject
 Leaf leaf;
 @Inject
 @Named("b")
 Node b;
 @Override
 public String name() {
  if (b == null)
   return String.format("nodeA(%s)", leaf);
  else
   return String.format("nodeAWithB(%s)", leaf);
 }
}

@Singleton
@Named("b")
class NodeB implements Node {
 Leaf leaf;
 @Inject
 @Named("a")
 Node a;
 @Inject
 public NodeB(Leaf leaf) {
  this.leaf = leaf;
 }

 @Override
 public String name() {
  if (a == null)
   return String.format("nodeB(%s)", leaf);
  else
   return String.format("nodeBWithA(%s)", leaf);
 }
}

class Leaf {
 @Inject
 Root root;
 int index;
 static int sequence;
 public Leaf() {
  index = sequence++;
 }

 public String toString() {
  if (root == null)
   return "leaf" + index;
  else
   return "leafwithroot" + index;
 }

}

public class Demo {
 public static void main(String[] args) {
  var injector = new Injector();
  injector.registerQualifiedClass(Node.class, NodeA.class);
  injector.registerQualifiedClass(Node.class, NodeB.class);
  var root = injector.getInstance(Root.class);
  System.out.println(root);
 }
}

上面這份代碼用到了iockids提供的所有功能。

  1. Root/NodeA/NodeB類是單例類
  2. Leaf類是非單例類
  3. 它們都使用了字段注入
  4. NodeB使用了構(gòu)造器注入
  5. NodeA和NodeB還使用了Qualifier名稱注入
  6. Leaf類中有Root類型的字段,這便是循環(huán)依賴
  7. NodeA中有NodeB字段,NodeB中有NodeA字段,這也是循環(huán)依賴

為了便于理解上述代碼,我畫了依賴圖


上面的代碼輸出如下

root(nodeAWithB(leafwithroot0), nodeBWithA(leafwithroot1))

從這個(gè)輸出中,我們也可以大致想象出依賴結(jié)構(gòu)。

iockids提供了豐富的注入錯(cuò)誤異常報(bào)告,防止用戶注入配置出錯(cuò)。

比如我們將上面的NodeA和NodeB的名稱都配置成一樣的a,就會(huì)曝出下面的錯(cuò)誤堆棧

iockids.InjectException: duplicated qualifier javax.inject.Named with the same class iockids.demo.Node
 at iockids.Injector.registerQualifiedClass(Injector.java:87)
 at iockids.Injector.registerQualifiedClass(Injector.java:70)
 at iockids.demo.Demo.main(Demo.java:106)

如果我們將NodeB的構(gòu)造器隨意加一個(gè)參數(shù)

 @Inject
 public NodeB(Leaf leaf, int k) {
  this.leaf = leaf;
 }

運(yùn)行時(shí)就會(huì)拋出下面的錯(cuò)誤

iockids.InjectException: no accessible constructor for injection class int
 at iockids.Injector.createNew(Injector.java:120)
 at iockids.Injector.createNew(Injector.java:94)
 at iockids.Injector.createFromParameter(Injector.java:167)
 at iockids.Injector.createFromConstructor(Injector.java:145)
 at iockids.Injector.createNew(Injector.java:123)
 at iockids.Injector.createFromQualified(Injector.java:216)
 at iockids.Injector.createFromField(Injector.java:173)
 at iockids.Injector.injectMembers(Injector.java:233)
 at iockids.Injector.createNew(Injector.java:136)
 at iockids.Injector.createFromQualified(Injector.java:216)
 at iockids.Injector.createFromField(Injector.java:173)
 at iockids.Injector.injectMembers(Injector.java:233)
 at iockids.Injector.createNew(Injector.java:136)
 at iockids.Injector.createNew(Injector.java:94)
 at iockids.Injector.getInstance(Injector.java:245)
 at iockids.demo.Demo.main(Demo.java:107)

項(xiàng)目開(kāi)源地址:https://github.com/pyloque/iockids (本地下載

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • 深入Spring Boot之ClassLoader的繼承關(guān)系和影響

    深入Spring Boot之ClassLoader的繼承關(guān)系和影響

    這篇文章主要介紹了深入Spring Boot之ClassLoader的繼承關(guān)系和影響,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Java中JSON處理工具類使用詳解

    Java中JSON處理工具類使用詳解

    這篇文章主要為大家詳細(xì)介紹了Java中JSON處理工具類的使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • mybatis-plus排除非表中字段的操作

    mybatis-plus排除非表中字段的操作

    這篇文章主要介紹了mybatis-plus排除非表中字段的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • 解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問(wèn)題

    解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問(wèn)題

    這篇文章主要介紹了解決@PathVariable出現(xiàn)點(diǎn)號(hào).時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • 淺談javaSE 面向?qū)ο?Object類toString)

    淺談javaSE 面向?qū)ο?Object類toString)

    下面小編就為大家?guī)?lái)一篇淺談javaSE 面向?qū)ο?Object類toString)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • Spring-cloud 注冊(cè)服務(wù)提供者搭建方法

    Spring-cloud 注冊(cè)服務(wù)提供者搭建方法

    本篇文章主要介紹了Spring-cloud 注冊(cè)服務(wù)提供者搭建方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • struts2中類型轉(zhuǎn)換實(shí)例代碼

    struts2中類型轉(zhuǎn)換實(shí)例代碼

    這篇文章主要介紹了struts2中類型轉(zhuǎn)換實(shí)例代碼,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • java 算法之希爾排序詳解及實(shí)現(xiàn)代碼

    java 算法之希爾排序詳解及實(shí)現(xiàn)代碼

    這篇文章主要介紹了java 算法之希爾排序詳解及實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java中hashMap遍歷的9種方式

    Java中hashMap遍歷的9種方式

    hashMap是非常重要的容器類,本文主要介紹了Java中hashMap遍歷的9種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析

    java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析

    這篇文章主要介紹了java字符串相加時(shí)的內(nèi)存表現(xiàn)和原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評(píng)論