国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

深入理解Spring中的Lookup(方法注入)

2024-07-14 08:40:52
字體:
來源:轉載
供稿:網友

前言

本文主要給大家介紹了關于Spring中Lookup(方法注入)的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹:

在使用Spring時,可能會遇到這種情況:一個單例的Bean依賴另一個非單例的Bean。如果簡單的使用自動裝配來注入依賴,就可能會出現一些問題,如下所示:

單例的Class A

@Componentpublic class ClassA { @Autowired private ClassB classB; public void printClass() {  System.out.println("This is Class A: " + this);  classB.printClass(); }}

非單例的Class B

@Component@Scope(value = SCOPE_PROTOTYPE)public class ClassB {  public void printClass() {    System.out.println("This is Class B: " + this);  }}

這里Class A采用了默認的單例scope,并依賴于Class B, 而Class B的scope是prototype,因此不是單例的,這時候跑個測試就看出這樣寫的問題:

@RunWith(SpringRunner.class)@ContextConfiguration(classes = {ClassA.class, ClassB.class})public class MyTest {  @Autowired  private ClassA classA;  @Test  public void simpleTest() {    for (int i = 0; i < 3; i++) {      classA.printClass();    }  }}

輸出的結果是:

This is Class A: ClassA@282003e1
This is Class B: ClassB@7fad8c79
This is Class A: ClassA@282003e1
This is Class B: ClassB@7fad8c79
This is Class A: ClassA@282003e1
This is Class B: ClassB@7fad8c79

可以看到,兩個類的Hash Code在三次輸出中都是一樣。Class A的值不變是可以理解的,因為它是單例的,但是Class B的scope是prototype卻也保持Hash Code不變,似乎也成了單例?

產生這種的情況的原因是,Class A的scope是默認的singleton,因此Context只會創建Class A的bean一次,所以也就只有一次注入依賴的機會,容器也就無法每次給Class A提供一個新的Class B。

不那么好的解決方案

要解決上述問題,可以對Class A做一些修改,讓它實現ApplicationContextAware。

@Componentpublic class ClassA implements ApplicationContextAware {  private ApplicationContext applicationContext;  public void printClass() {    System.out.println("This is Class A: " + this);    getClassB().printClass();  }  public ClassB getClassB() {    return applicationContext.getBean(ClassB.class);  }  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {    this.applicationContext = applicationContext;  }}

這樣就能夠在每次需要到Class B的時候手動去Context里找到新的bean。再跑一次測試后得到了以下輸出:

This is Class A: com.devhao.ClassA@4df828d7
This is Class B: com.devhao.ClassB@31206beb
This is Class A: com.devhao.ClassA@4df828d7
This is Class B: com.devhao.ClassB@3e77a1ed
This is Class A: com.devhao.ClassA@4df828d7
This is Class B: com.devhao.ClassB@3ffcd140

可以看到Class A的Hash Code在三次輸出中保持不變,而Class B的卻每次都不同,說明問題得到了解決,每次調用時用到的都是新的實例。

但是這樣的寫法就和Spring強耦合在一起了,Spring提供了另外一種方法來降低侵入性。

@Lookup

Spring提供了一個名為@Lookup的注解,這是一個作用在方法上的注解,被其標注的方法會被重寫,然后根據其返回值的類型,容器調用BeanFactory的getBean()方法來返回一個bean。

@Componentpublic class ClassA {  public void printClass() {    System.out.println("This is Class A: " + this);    getClassB().printClass();  }  @Lookup  public ClassB getClassB() {    return null;  }}

可以發現簡潔了很多,而且不再和Spring強耦合,再次運行測試依然可以得到正確的輸出。
被標注的方法的返回值不再重要,因為容器會動態生成一個子類然后將這個被注解的方法重寫/實現,最終調用的是子類的方法。

使用的@Lookup的方法需要符合如下的簽名:

<public|protected> [abstract] <return-type> theMethodName(no-arguments);

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 柏乡县| 沁阳市| 辽中县| 万载县| 台北县| 新郑市| 永昌县| 古丈县| 贵州省| 武清区| 石城县| 宜阳县| 额济纳旗| 沈丘县| 晋城| 远安县| 罗山县| 龙山县| 巴林右旗| 襄城县| 会理县| 辽宁省| 奎屯市| 阆中市| 察雅县| 南皮县| 新乡市| 阿坝县| 襄垣县| 广灵县| 阳曲县| 克什克腾旗| 敦煌市| 南充市| 虞城县| 平顶山市| 马尔康县| 成安县| 辉县市| 紫阳县| 东阿县|