最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot this調(diào)用@Bean效果詳解

 更新時(shí)間:2023年02月03日 10:57:40   作者:愿做無(wú)知一猿  
這篇文章主要介紹了在一個(gè)@Bean方法內(nèi),this調(diào)用同一個(gè)類的@Bean方法會(huì)有什么效果,我們可以通過(guò)bean的名稱、bean的類型或者bean的名稱+類型來(lái)獲取容器中的bean

在一個(gè)@Bean方法內(nèi),this調(diào)用同一個(gè)類的@Bean方法會(huì)有什么效果呢?

思考的起源

首先上代碼:

public class BeanOne { 
}
public class BeanTwo {
    public BeanTwo(BeanOne beanOne){
    }
}
@Configuration
public class BeanConfigTest {
    @Bean
    @ConditionalOnMissingBean
    public BeanOne beanOne() {
        System.err.println("帶有@ConditionalOnMissingBean的默認(rèn) BeanOne 產(chǎn)生------");
        return new BeanOne();
    }
    @Bean
    public BeanTwo beanTwo() {
        return new BeanTwo(this.beanOne());
    }
}

? 可以看到上述三個(gè)類,其中BeanOne就是一個(gè)默認(rèn)的Bean實(shí)現(xiàn),標(biāo)注了@ConditionalOnMissingBean代表它可以被覆蓋;BeanTwo是一個(gè)使用BeanOne的類,類似于注入;BeanConfigTest就是用來(lái)注冊(cè)這倆Bean的,可以看到在BeanTwo這個(gè)里面,直接使用了this.beanOne(),我一開始的想法就是,this調(diào)用,那始終調(diào)用的都是beanOne()這個(gè)方法呀,那不就代表著BeanOne不能被覆蓋了。

? 但是,當(dāng)我將BeanOne加上@Component注解之后,運(yùn)行程序,會(huì)發(fā)現(xiàn),控制臺(tái)根本沒有輸出我打印的那句話,那就可以猜測(cè) this.beanOne()其實(shí)并不是簡(jiǎn)單的方法調(diào)用方法。

查找信息

閱讀@Bean上的注釋:

@Bean Methods in @Configuration Classes
Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original 'Spring JavaConfig' project which require CGLIB subclassing of each such configuration class at runtime. As a consequence, @Configuration classes and their factory methods must not be marked as final or private in this mode. For example:
   @Configuration
   public class AppConfig {
       @Bean
       public FooService fooService() {
           return new FooService(fooRepository());
       }
       @Bean
       public FooRepository fooRepository() {
           return new JdbcFooRepository(dataSource());
       }
       // ...
   }

? 簡(jiǎn)要概述就是:

Spring會(huì)對(duì)每個(gè)@Configuration標(biāo)注的類進(jìn)行CGLIB子類化,在一個(gè)Bean內(nèi)使用方法調(diào)用另一個(gè)Bean,就像是getBean()查找一樣。

? 從它注釋上的描述可以總結(jié)出,像this.beanOne()這類方法調(diào)用,其實(shí)就類似于getBean()去獲取一個(gè)名叫beanOneBean。那么上面的輸出結(jié)果就能解釋了。

? 上面這段注釋下面,緊跟著一段注釋,一起看一下:

@Bean Lite Mode
@Bean methods may also be declared within classes that are not annotated with @Configuration. For example, bean methods may be declared in a @Component class or even in a plain old class. In such cases, a @Bean method will get processed in a so-called 'lite' mode.
Bean methods in lite mode will be treated as plain factory methods by the container (similar to factory-method declarations in XML), with scoping and lifecycle callbacks properly applied. The containing class remains unmodified in this case, and there are no unusual constraints for the containing class or the factory methods.
In contrast to the semantics for bean methods in @Configuration classes, 'inter-bean references' are not supported in lite mode. Instead, when one @Bean-method invokes another @Bean-method in lite mode, the invocation is a standard Java method invocation; Spring does not intercept the invocation via a CGLIB proxy. This is analogous to inter-@Transactional method calls where in proxy mode, Spring does not intercept the invocation — Spring does so only in AspectJ mode.
For example:
   @Component
   public class Calculator {
       public int sum(int a, int b) {
           return a+b;
       }
       @Bean
       public MyBean myBean() {
           return new MyBean();
       }
   }

? 簡(jiǎn)要概述就是:

@Component標(biāo)注的類中,你使用@Bean標(biāo)注的方法處于一種叫做lite模式下,lite模式中的Bean方法將被容器視為普通工廠方法,lite模式中的Bean,不支持Bean間的相互調(diào)用,如果相互調(diào)用,那么將會(huì)被視為標(biāo)準(zhǔn)的Java方法調(diào)用,Spring不會(huì)通過(guò)CGLIB為當(dāng)前類生成子類。最后他說(shuō),這類似于內(nèi)部 @Transactional方法調(diào)用,在代理模式下,Spring不會(huì)攔截調(diào)用;但是僅在AspectJ模式下,Spring會(huì)攔截調(diào)用。好像也是,標(biāo)注@Transcational的方法是不能直接相互調(diào)用的。

? 那用上面的例子試一下看看,是不是變成了普通Java方法調(diào)用了:

@Component
public class BeanOne {
}
public class BeanTwo {
    public BeanTwo(BeanOne beanOne){
    }
}
@Component
//@Configuration
public class BeanConfigTest {
    /**
     * @Bean 創(chuàng)建的默認(rèn)是單例Bean
     */
    @Bean
    @ConditionalOnMissingBean
    public BeanOne beanOne() {
        System.err.println("帶有@ConditionalOnMissingBean的默認(rèn) BeanOne 產(chǎn)生------");
        return new BeanOne();
    }
    @Bean
    public BeanTwo beanTwo() {
        return new BeanTwo(this.beanOne());
    }
}

? 此時(shí)BeanOne上標(biāo)注了@Component,但是打印了輸出語(yǔ)句,可見其變成了普通方法調(diào)用。

更遠(yuǎn)一步

Bean的Full和Lite模式

? 當(dāng)@Bean方法在沒有標(biāo)注@Configuration注釋的類中聲明時(shí),它們被稱為L(zhǎng)ite模式的Bean。例如:在@Component中聲明的@Bean方法,甚至只是在一個(gè)非常普通的類中聲明的Bean方法,都被認(rèn)為是Lite版的配置類。和Full模式的@Configuration不同,Lite模式的@Bean方法不能聲明Bean之間的依賴關(guān)系。因此,這樣的@Bean方法不應(yīng)該調(diào)用其他@Bean方法。每個(gè)這樣的方法實(shí)際上只是一個(gè)特定Bean引用的工廠方法(factory-method),沒有任何特殊的運(yùn)行時(shí)語(yǔ)義。

? 怎么確定一個(gè)Bean是不是Lite模式呢?

只要不標(biāo)識(shí)@Configuration(proxyBeanMethods=true)其他都是lite模式。(當(dāng)然,標(biāo)注了的就是Full模式啦)

上述例子的spring-context版本是6.0.2,其中@Configuration的屬性proxyBeanMethods的默認(rèn)值是true。

? 那么proxyBeanMethods為true和false有什么使用上的區(qū)別呢?

設(shè)置為false此時(shí)bean是lite模式:

此時(shí)運(yùn)行時(shí)不再需要給對(duì)應(yīng)類生成CGLIB子類,提高了運(yùn)行性能,降低了啟動(dòng)時(shí)間,但是不能聲明@Bean之間的依賴,也就是說(shuō)不能通過(guò)方法調(diào)用來(lái)依賴其它Bean。

設(shè)置為true時(shí)為Full模式

此時(shí)配置類會(huì)被CGLIB增強(qiáng)(生成代理對(duì)象),放進(jìn)IoC容器內(nèi)的是代理,方法相互調(diào)用能夠保證是同一個(gè)實(shí)例,都指向IoC內(nèi)的那個(gè)單例,可以支持通過(guò)常規(guī)Java調(diào)用相同類的@Bean方法而保證是容器內(nèi)的Bean,但是運(yùn)行時(shí)會(huì)給該類生成一個(gè)CGLIB子類放進(jìn)容器,有一定的性能、時(shí)間開銷。

到此這篇關(guān)于SpringBoot this調(diào)用@Bean效果詳解的文章就介紹到這了,更多相關(guān)SpringBoot調(diào)用@Bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springmvc?html資源請(qǐng)求404的問(wèn)題解決并分析

    springmvc?html資源請(qǐng)求404的問(wèn)題解決并分析

    這篇文章主要介紹了springmvc?html資源請(qǐng)求404的問(wèn)題解決并分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java?泛型超詳細(xì)入門講解

    Java?泛型超詳細(xì)入門講解

    這篇文章主要介紹了Java基礎(chǔ)泛型詳情,泛型是JDK5中引入的特性,它提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許在編譯時(shí)檢測(cè)到非法的類型,下面文章的詳細(xì)介紹,需要的朋友可以參考一下
    2022-04-04
  • java異常與錯(cuò)誤處理基本知識(shí)

    java異常與錯(cuò)誤處理基本知識(shí)

    本文內(nèi)容是java的異常與錯(cuò)誤處理基本知識(shí)
    2013-11-11
  • Java 精煉解讀方法的定義與使用

    Java 精煉解讀方法的定義與使用

    Java語(yǔ)言中的“方法”(Method)在其他語(yǔ)言當(dāng)中也可能被稱為“函數(shù)”(Function)。對(duì)于一些復(fù)雜的代碼邏輯,如果希望重復(fù)使用這些代碼,并且做到“隨時(shí)任意使用”,那么就可以將這些代碼放在一個(gè)大括號(hào)“{}”當(dāng)中,并且起一個(gè)名字。使用的時(shí)候,直接找到名字調(diào)用即可
    2022-03-03
  • JavaSwing基礎(chǔ)之Layout布局相關(guān)知識(shí)詳解

    JavaSwing基礎(chǔ)之Layout布局相關(guān)知識(shí)詳解

    上次我們說(shuō)到View的Mearsure流程,今天接著說(shuō)說(shuō)layout. 關(guān)于layout,很多朋友知道它是負(fù)責(zé)布局的,那么具體是怎么布局的?viewGroup和view的layout方法又有什么不同?一起來(lái)看看吧,需要的朋友可以參考下
    2021-05-05
  • Spring @Async 的使用與實(shí)現(xiàn)的示例代碼

    Spring @Async 的使用與實(shí)現(xiàn)的示例代碼

    本篇文章主要介紹了Spring @Async 的使用與實(shí)現(xiàn)的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java實(shí)現(xiàn)用位運(yùn)算維護(hù)狀態(tài)碼

    Java實(shí)現(xiàn)用位運(yùn)算維護(hù)狀態(tài)碼

    位運(yùn)算是一種非常高效的運(yùn)算方式,在算法考察中比較常見,那么業(yè)務(wù)代碼中我們?nèi)绾问褂梦贿\(yùn)算呢,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下吧
    2024-03-03
  • 如何使用CountDownLatch同步j(luò)ava多線程

    如何使用CountDownLatch同步j(luò)ava多線程

    這篇文章主要介紹了如何使用CountDownLatch同步j(luò)ava多線程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Idea 搭建Spring源碼環(huán)境的超詳細(xì)教程

    Idea 搭建Spring源碼環(huán)境的超詳細(xì)教程

    這篇文章主要介紹了Idea 搭建Spring源碼環(huán)境,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java數(shù)組中的元素刪除并實(shí)現(xiàn)向前移的代碼

    Java數(shù)組中的元素刪除并實(shí)現(xiàn)向前移的代碼

    這篇文章主要介紹了Java數(shù)組中的元素刪除并實(shí)現(xiàn)向前移的代碼的相關(guān)資料,需要的朋友可以參考下
    2016-05-05

最新評(píng)論

贡嘎县| 郁南县| 岳阳县| 安新县| 昭平县| 澳门| 浑源县| 左贡县| 和顺县| 浮梁县| 达孜县| 霍州市| 鄱阳县| 钟山县| 平度市| 临高县| 沙雅县| 永清县| 浦东新区| 文山县| 交城县| 盘锦市| 黄浦区| 通河县| 金湖县| 洪泽县| 施甸县| 汉川市| 莲花县| 玉门市| 蒙山县| 禹州市| 肥西县| 莱州市| 抚松县| 开鲁县| 湖北省| 龙岩市| 汾阳市| 石台县| 宣武区|