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

SpringBoot this調用@Bean效果詳解

 更新時間:2023年02月03日 10:57:40   作者:愿做無知一猿  
這篇文章主要介紹了在一個@Bean方法內,this調用同一個類的@Bean方法會有什么效果,我們可以通過bean的名稱、bean的類型或者bean的名稱+類型來獲取容器中的bean

在一個@Bean方法內,this調用同一個類的@Bean方法會有什么效果呢?

思考的起源

首先上代碼:

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

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

? 但是,當我將BeanOne加上@Component注解之后,運行程序,會發(fā)現(xiàn),控制臺根本沒有輸出我打印的那句話,那就可以猜測 this.beanOne()其實并不是簡單的方法調用方法。

查找信息

閱讀@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());
       }
       // ...
   }

? 簡要概述就是:

Spring會對每個@Configuration標注的類進行CGLIB子類化,在一個Bean內使用方法調用另一個Bean,就像是getBean()查找一樣。

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

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

@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();
       }
   }

? 簡要概述就是:

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

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

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

? 此時BeanOne上標注了@Component,但是打印了輸出語句,可見其變成了普通方法調用。

更遠一步

Bean的Full和Lite模式

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

? 怎么確定一個Bean是不是Lite模式呢?

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

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

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

設置為false此時bean是lite模式:

此時運行時不再需要給對應類生成CGLIB子類,提高了運行性能,降低了啟動時間,但是不能聲明@Bean之間的依賴,也就是說不能通過方法調用來依賴其它Bean。

設置為true時為Full模式

此時配置類會被CGLIB增強(生成代理對象),放進IoC容器內的是代理,方法相互調用能夠保證是同一個實例,都指向IoC內的那個單例,可以支持通過常規(guī)Java調用相同類的@Bean方法而保證是容器內的Bean,但是運行時會給該類生成一個CGLIB子類放進容器,有一定的性能、時間開銷。

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

相關文章

  • java實現(xiàn)抖音飛機大作戰(zhàn)

    java實現(xiàn)抖音飛機大作戰(zhàn)

    這篇文章主要為大家詳細介紹了java實現(xiàn)抖音飛機大作戰(zhàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Spring 使用xml配置AOP的過程詳解

    Spring 使用xml配置AOP的過程詳解

    在之前的學習中,都是使用注解的方式進行AOP的配置.其實使用xml配置文件也可以配置AOP,本文給大家分享Spring 使用xml配置AOP的過程,感興趣的朋友一起看看吧
    2023-11-11
  • springboot優(yōu)雅獲取前端參數(shù)的方法詳解

    springboot優(yōu)雅獲取前端參數(shù)的方法詳解

    現(xiàn)在的項目基本上都是前后端分離的項目,如何打通前后端,接收前端傳過來的參數(shù)呢,這篇文章小編就來和大家詳細介紹一下springboot如何優(yōu)雅的獲取前端參數(shù)吧
    2024-03-03
  • 使用easyexcel導出的excel文件,使用poi讀取時異常處理方案

    使用easyexcel導出的excel文件,使用poi讀取時異常處理方案

    這篇文章主要介紹了使用easyexcel導出的excel文件,使用poi讀取時異常處理方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Nacos框架服務注冊實現(xiàn)流程

    Nacos框架服務注冊實現(xiàn)流程

    這篇文章主要介紹了SpringCloud服務注冊之nacos實現(xiàn)過程,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • SpringbootJPA分頁 PageRequest過時的替代方法

    SpringbootJPA分頁 PageRequest過時的替代方法

    這篇文章主要介紹了SpringbootJPA分頁 PageRequest過時的替代方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 如何提高java代碼的重用性

    如何提高java代碼的重用性

    在本篇文章中小編給各位分享了關于如何提高java代碼的重用性的相關知識點內容,有需要的朋友們參考下。
    2019-07-07
  • Java中的concurrenthashmap集合詳細剖析

    Java中的concurrenthashmap集合詳細剖析

    這篇文章主要介紹了Java中的concurrenthashmap集合詳細剖析,有參構造后第一次put時會進行初始化,由源碼可知,會先判斷所傳入的容量是否>=最大容量的一半,如果滿足條件,就會將容量修改為最大值,反之則會將容量改為所傳入數(shù)*1.5+1,需要的朋友可以參考下
    2023-11-11
  • SpringBoot實現(xiàn)掃碼登錄的示例代碼

    SpringBoot實現(xiàn)掃碼登錄的示例代碼

    本文主要介紹了SpringBoot實現(xiàn)掃碼登錄的示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • MyBatis嵌套查詢collection報錯:org.apache.ibatis.exceptions.TooManyResultsException

    MyBatis嵌套查詢collection報錯:org.apache.ibatis.exceptions.TooMany

    本文主要介紹了MyBatis嵌套查詢collection報錯:org.apache.ibatis.exceptions.TooManyResultsException,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-09-09

最新評論