<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          終于搞懂了 @Configuration 和 @Component 的區(qū)別

          共 6968字,需瀏覽 14分鐘

           ·

          2023-03-11 05:06

          程序員的成長之路
          互聯(lián)網(wǎng)/程序員/技術(shù)/資料共享 
          關(guān)注


          閱讀本文大概需要 3.5 分鐘。

          來自:blog.csdn.net/qq_29025955/article/details/128818957

          一句話概括就是 @Configuration 中所有帶 @Bean 注解的方法都會被動態(tài)代理,因此調(diào)用該方法返回的都是同一個實例。
          理解:調(diào)用@Configuration類中的@Bean注解的方法,返回的是同一個示例;而調(diào)用@Component類中的@Bean注解的方法,返回的是一個新的實例。
          注意:上面說的調(diào)用,而不是從spring容器中獲取! 見最下面的示例 1 及 示例 2
          下面看看實現(xiàn)的細(xì)節(jié)。

          @Configuration 注解:

          @Target(ElementType.TYPE)
          @Retention(RetentionPolicy.RUNTIME)
          @Documented
          @Component
          public @interface Configuration {
              String value() default "";
          }

          從定義來看, @Configuration注解本質(zhì)上還是@Component,因此 <context:component-scan/> 或者 @ComponentScan 都能處理@Configuration注解的類。
          @Configuration標(biāo)記的類必須符合下面的要求:
          • 配置類必須以類的形式提供(不能是工廠方法返回的實例),允許通過生成子類在運行時增強(qiáng)(cglib 動態(tài)代理)。

          • 配置類不能是final 類(沒法動態(tài)代理)。

          • 配置注解通常為了通過 @Bean注解生成 Spring 容器管理的類,

          • 配置類必須是非本地的(即不能在方法中聲明,不能是 private)。

          • 任何嵌套配置類都必須聲明為static。

          • @Bean方法可能不會反過來創(chuàng)建進(jìn)一步的配置類(也就是返回的 bean 如果帶有 @Configuration,也不會被特殊處理,只會作為普通的 bean)。

          @Bean 注解方法執(zhí)行策略

          先給一個簡單的示例代碼:

          @Configuration
          public class MyBeanConfig {

              @Bean
              public Country country(){
                  return new Country();
              }

              @Bean
              public UserInfo userInfo(){
                  return new UserInfo(country());
              }

          }

          相信大多數(shù)人第一次看到上面 userInfo() 中調(diào)用 country()時,會認(rèn)為這里的 Country和上面 @Bean方法返回的 Country 可能不是同一個對象,因此可能會通過下面的方式來替代這種方式:
          • @Autowired
          • private Country country;
          實際上不需要這么做(后面會給出需要這樣做的場景),直接調(diào)用country() 方法返回的是同一個實例。

          @Component 注解

          @Component注解并沒有通過 cglib 來代理@Bean 方法的調(diào)用,因此像下面這樣配置時,就是兩個不同的 country。

          @Component
          public class MyBeanConfig {

              @Bean
              public Country country(){
                  return new Country();
              }

              @Bean
              public UserInfo userInfo(){
                  return new UserInfo(country());
              }

          }

          有些特殊情況下,我們不希望 MyBeanConfig被代理(代理后會變成WebMvcConfig$$EnhancerBySpringCGLIB$$8bef3235293)時,就得用 @Component,這種情況下,上面的寫法就需要改成下面這樣:

          @Component
          public class MyBeanConfig {

              @Autowired
              private Country country;

              @Bean
              public Country country(){
                  return new Country();
              }

              @Bean
              public UserInfo userInfo(){
                  return new UserInfo(country);
              }

          }

          這種方式可以保證使用的同一個 Country 實例。
          示例 1:調(diào)用@Configuration類中的@Bean注解的方法,返回的是同一個示例
          第一個bean類

          package com.xl.test.logtest.utils;

          public class Child {
           private String name = "the child";

           public String getName() {
            return name;
           }

           public void setName(String name) {
            this.name = name;
           }
          }

          第二個bean類

          package com.xl.test.logtest.utils;

          public class Woman {
           
           private String name = "the woman";
           
           private Child child;

           public String getName() {
            return name;
           }

           public void setName(String name) {
            this.name = name;
           }

           public Child getChild() {
            return child;
           }

           public void setChild(Child child) {
            this.child = child;
           }
          }

          @Configuration

          package com.xl.test.logtest.utils;

          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.stereotype.Component;

          @Configuration
          //@Component
          public class Human {
           
           @Bean
           public Woman getWomanBean() {
            Woman woman = new Woman();
            woman.setChild(getChildBean()); // 直接調(diào)用@Bean注解的方法方法getChildBean()
            return woman;
           }
           
           @Bean
           public Child getChildBean() {
            return new Child();
           }
          }

          測試類 I
          本測試類為一個配置類,這樣啟動項目是就可以看到測試效果,更加快捷;也可以使用其他方式測試見下面的測試類 II

          package com.xl.test.logtest.utils;

          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.context.annotation.Configuration;

          @Configuration
          public class Man {
           
           @Autowired
           public Man(Woman wn, Child child) {
            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            System.out.println(wn.getChild() == child ? "是同一個對象":"不是同一個對象");
           }
          }

          啟動項目,查看輸出結(jié)果:
          測試類 II

          package com.xl.test.logtest.controller;

          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.web.bind.annotation.GetMapping;
          import org.springframework.web.bind.annotation.RestController;

          import com.xl.test.logtest.utils.Child;
          import com.xl.test.logtest.utils.Woman;

          @RestController
          public class LogTestController {
           @Autowired
           Woman woman ;
           
           @Autowired
           Child child;
           
           @GetMapping("/log")
           public String log() {
            return woman.getChild() == child ? "是同一個對象":"不是同一個對象";
           }
          }

          瀏覽器訪問項目,查看結(jié)果;輸入localhost:8080/log
          示例 2 :調(diào)用@Component類中的@Bean注解的方法,返回的是一個新的實例。
          測試代碼,只需要將@Configuration改為@Component即可!其他的均不變

          package com.xl.test.logtest.utils;

          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.stereotype.Component;

          //@Configuration
          @Component
          public class Human {
           
           @Bean
           public Woman getWomanBean() {
            Woman woman = new Woman();
            woman.setChild(getChildBean()); // 直接調(diào)用@Bean注解的方法方法getChildBean()
            return woman;
           }
           
           @Bean
           public Child getChildBean() {
            return new Child();
           }
          }

          測試 :
          控制臺和瀏覽器展示,均符合預(yù)期!
          <END>

          推薦閱讀:

          牛逼哄哄的 BitMap,到底牛逼在哪?

          使用 try-catch 捕獲異常會影響性能嗎?

          互聯(lián)網(wǎng)初中高級大廠面試題(9個G)

          內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬并發(fā)、消息隊列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper......等技術(shù)棧!

          ?戳閱讀原文領(lǐng)?。?/span>                                  朕已閱 

          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  人妻av中文无码 人妻-X88AⅤ | 精品人伦一区二区三区蜜桃网站 | 天天色天| chaopeng超碰永久 | 天天曰,天天干 |