詳解Spring中Lookup注解的使用
我們知道在spring容器中單獨(dú)的一個(gè)抽象類(lèi)是不能成為一個(gè)bean的,那么有沒(méi)有辦法呢?這個(gè)時(shí)候我們可以使用Lookup注解,我們可以看下spring的掃描bean部分邏輯。我們知道在spring中要想成為一個(gè)bean,必須先生成BeanDefinition對(duì)象,如果一個(gè)抽象類(lèi)中沒(méi)有含有Lookup注解的方法,在spring掃描時(shí)就會(huì)被排除掉。
/**
* 1、判斷是不是獨(dú)立的類(lèi),非靜態(tài)內(nèi)部類(lèi)則無(wú)法生成bean,
* 2、判斷是不是接口或者抽象類(lèi)(有一種特殊情況),是則無(wú)法生成
* 3、判斷如果是抽象類(lèi),但是里面有某個(gè)方法上面加油@lookup注解,則也可以生成bean
* Determine whether the given bean definition qualifies as candidate.
* <p>The default implementation checks whether the class is not an interface
* and not dependent on an enclosing class.
* <p>Can be overridden in subclasses.
* @param beanDefinition the bean definition to check
* @return whether the bean definition qualifies as a candidate component
*/
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
return (metadata.isIndependent() && (metadata.isConcrete() ||
(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
}
下面我們就驗(yàn)證下,不使用Lookup注解的情況
@Component
public abstract class C1 {
}
運(yùn)行結(jié)果報(bào)錯(cuò)

在抽象類(lèi)中隨便寫(xiě)個(gè)方法,然后方法上面增加Lookup注解
@Component
public abstract class C1 {
@Lookup
public void a(){}
}
運(yùn)行結(jié)果,正常輸出,通過(guò)cglib代理生成新的類(lèi)

但是一般很少這樣用,另外一種場(chǎng)景可能會(huì)用到。在某個(gè)單例bean中使用另外一個(gè)bean對(duì)象,但是每次又想返回的對(duì)象不同。但是spring在容器中注入bean的時(shí)候,scope默認(rèn)的是單例模式,也就是說(shuō)在整個(gè)應(yīng)用中只能創(chuàng)建一個(gè)實(shí)例。當(dāng)scope為PROTOTYPE類(lèi)型的時(shí)候,在每次注入的時(shí)候會(huì)自動(dòng)創(chuàng)建一個(gè)新的bean實(shí)例。但是當(dāng)一個(gè)單例模式的bean去引用PROTOTYPE類(lèi)型的bean的時(shí)候,PROTOTYPE類(lèi)型的bean也會(huì)變成單例。
@Component
public class D3 {
@Autowired
private E4 e4;
public void a(){
System.out.println(this.e4);
}
}
@Component
public class E4 {
}
輸出結(jié)果,可以看到每次打印出來(lái)的對(duì)象是同一個(gè)

使用Lookup注解
@Component
public class D3 {
public void a(){
System.out.println(this.a1());
}
@Lookup
public E4 a1(){
return null;
}
}
運(yùn)行輸出結(jié)果,每次輸出的結(jié)果已經(jīng)不相同了,已經(jīng)達(dá)到了我們的需求

這是什么原因?qū)е碌哪??還有就是我們a1方法返回的是空,但是輸出的結(jié)果為啥也有值呢?
因?yàn)閟pring在遇到這種標(biāo)有Lookup注解的方法時(shí),會(huì)重寫(xiě)該方法,然后返回結(jié)果,所以我們自己定義的方法不管有沒(méi)有返回值已經(jīng)沒(méi)關(guān)系了。
到此這篇關(guān)于詳解Spring中Lookup注解的使用的文章就介紹到這了,更多相關(guān)Spring Lookup注解的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot日志收集及鏈路追蹤實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Spring Boot日志收集及鏈路追蹤實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
新聞列表的分頁(yè)查詢(xún)java代碼實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了新聞列表的分頁(yè)查詢(xún)java代碼實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2016-08-08
一文了解Java讀寫(xiě)鎖ReentrantReadWriteLock的使用
ReentrantReadWriteLock稱(chēng)為讀寫(xiě)鎖,它提供一個(gè)讀鎖,支持多個(gè)線程共享同一把鎖。這篇文章主要講解一下ReentrantReadWriteLock的使用和應(yīng)用場(chǎng)景,感興趣的可以了解一下2022-10-10
Java concurrency集合之ConcurrentLinkedQueue_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java concurrency集合之ConcurrentLinkedQueue,需要的朋友可以參考下2017-06-06
Java編程幾個(gè)循環(huán)實(shí)例代碼分享
這篇文章主要介紹了Java編程幾個(gè)循環(huán)實(shí)例代碼分享,多看多練,小編覺(jué)得還是挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-10-10
SpringBoot使用ExceptionHandler做異常處理
這篇文章主要介紹了SpringBoot使用ExceptionHandler做異常處理,這篇文章通過(guò)多種方法案例來(lái)介紹該項(xiàng)技術(shù)的使用,需要的朋友可以參考下2021-06-06
Spring Security permitAll()不允許匿名訪問(wèn)的操作
這篇文章主要介紹了Spring Security permitAll()不允許匿名訪問(wèn)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
如何基于Autowired對(duì)構(gòu)造函數(shù)進(jìn)行注釋
這篇文章主要介紹了如何基于Autowired對(duì)構(gòu)造函數(shù)進(jìn)行注釋,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
在SpringBoot中無(wú)縫整合Dubbo的實(shí)現(xiàn)過(guò)程
微服務(wù)架構(gòu)已經(jīng)成為現(xiàn)代應(yīng)用開(kāi)發(fā)的熱門(mén)趨勢(shì),而Dubbo作為一款強(qiáng)大的分布式服務(wù)框架,與Spring?Boot的結(jié)合是構(gòu)建高性能微服務(wù)應(yīng)用的理想選擇,本文將詳細(xì)介紹如何在SpringBoot中無(wú)縫整合Dubbo,需要的朋友可以參考下2024-01-01

