Aware接口的一些看法

關於 spring 中的 xxaware接口,aware 的意思是

意識到,對。。。有興趣

也就是說實現了 aware 接口意味着對這些內容有興趣。

比如ApplicationEventPublisherAware意味着對ApplicationEventPublisher有興趣,BeanNameAware則表明對BeanName有興趣

在 spring 中存在一個標記接口,就叫Awarespring 中所有的 aware 類的接口都繼承了這個接口,而所有的 Aware 接口也如其 doc 所說

The actual method signature is determined by individual subinterfaces but should typically consist of just one void-returning method that accepts a single argument.

提供了一個 setxx 的 void 函數。

也許有些同學還不知道,其實這種方法也屬於 DI的一種,名爲接口注入。

我們一般情況下最經常使用的是 spring 提供的 set 注入和構造器注入,但是在有些時候需要訪問 spring 的bean 時,使用 Aware 接口也許是一個更好的選擇,至於爲什麼。。。

我認爲這種接口形式的注入更能說明其特徵,這個類是關心這部分內容的,也就是說它應該依賴了這部分內容,畢竟如非必要勿增實體,但最好是在需要說明特徵時才使用這種方式,其他依賴的情況其實用 set 和 構造器更方便,並且耦合更加鬆散。

在我自己的項目中有時候也會不得已進行到這一步,某些接口都需要一個成員,成員需要在構造實現類時進行注入,就會增加一個接口,專門用於訪問這個成員,之前不知道取什麼名字好,一般都是 xxd 或者 xxed,後來學習了 spring 的 aware 之後就都取了這個名字xxAware,看起來也順眼多了。

比如我希望所有 handler 和 executor接口在執行時打印日誌都能夠打印 name,創建一個如下接口

interface Named{
  void setName(String name);
} 

而用下面這個接口看起來就更順眼一些

interface NameAware{
  void setName(String name);
} 

擴展操作

關於 這個 aware 其實也可以解決下面這個問題

如何在自己 new 出來的對象中訪問 spring 管理的 bean

一般腦洞不是特別大的情況下,詢問百度同學,會找到一個 BeanGet 的類,其實現了 ApplicationContextAware 接口,並且其set 函數實際上是給一個靜態變量賦值。看起來沒什麼問題,用起來稍微注意一下接口的訪問時機就好,但總覺得有點變扭,畢竟成員函數操作類變量。

我之前也是這樣子做的,但是後來突然開竅了,可以用下面這種更加自然的方式實現

假設需要手動 new 的類爲 A,A需要依賴的bean 的類型爲 B,手動new A 類的bean 爲 C

  1. 聲明一個需要依賴的 bean類型的 aware 接口也就是BAware

  2. 在會自行創建實例的 bean 中,也就是 C,注入需要依賴的 bean,也就是 B

  3. 在實現類中實現 AAware 接口

  4. 使用 instanceof 訪問接口

原始

interface T{
  //t 的接口
}
class A implements T{
  B b;
  //獲取 b
  b=BeanGet.getBean("b",B.class);
  //
}
class C{
  void createA(){
    new A();
  }
}

自然的方式

interface BAware{
  void setB(B b);
}
class A implements T,AAware{
  B b;
  //獲取 b
  //b=BeanGet.getBean("b",B.class);不用
  //
  
}
class C{
  B b;//注入到 C
  void createA(){
    T t=new A();
    if(t instanceof AAware)
      t.setB(b)
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章