成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

@ConfigurationProperties該如何裝載到Spring容器中呢?

開發(fā) 前端
所以對于配置注解ConfigurationProperties?的類不要使用使用@Component?注解讓Spring管理,更推薦的做法是使用@EnableConfigurationProperties注解進行裝載。

問題描述

最近項目中遇到了一個Spring中@ConfigurationProperties注解的問題,如下:

  1. 定義了一個注解了@ConfigurationProperties的User Bean。
@ConfigurationProperties(prefix = "my.user")
@Component
@Data
public class User {

    private String userName;
}
  1. 通過@Autowired使用UserBean,沒有問題。
@RestController
@RequestMapping("/config")
@EnableConfigurationProperties(User.class)
public class UserConfigController {

    @Autowired
    private User user;

    @GetMapping("/username1")
    public String username1() {
        return user.getUserName();
    }
}

圖片圖片

  1. 但是,有個同事修改了下變量名為user1,自信的以為沒有問題,就提交測試了,然后直接報錯了。
@RestController
@RequestMapping("/config")
@EnableConfigurationProperties(User.class)
public class UserConfigController {

    @Autowired
    private User user1;

    @GetMapping("/username2")
    public String username2() {
        return user1.getUserName();
    }
}

報錯如下圖所示:

圖片圖片

這是怎么一回事呢,修改個變量名都能報錯?

原因分析

根據(jù)報錯信息不難分析出來主要原因在于User類在Spring容器中兩個Bean對象,bean name分別是“user”和“my.user-com.alvinlkk.bean.User”。

使用@Autwired裝配,實際上不只是根據(jù)類型裝配,如果匹配到同類型有多個Bean對象,默認會去找和變量名“user”同名的Bean,所以不會報錯。如果修改變量名改成user1, 它就匹配到兩個Bean對象,然后用bean name=user1無法找到合適的,自然就報錯了。

那么為什么會出現(xiàn)兩個Bean呢?

  1. 因為使用@Component注解,創(chuàng)建了一個名稱為“user”的Bean。

圖片圖片

  1. 使用了@EnableConfigurationProperties注解創(chuàng)建了名稱為my.user-com.alvinlkk.bean.User的Bean。

最佳實踐最佳實踐

使用@ConfigurationProperties注解的Bean的時候,建議通過使用@EnableConfigurationProperties創(chuàng)建Bean。

源碼解析

刨根問底,我們繼續(xù)從Spring源碼層面深入了解下這個問題的產(chǎn)生的根源。Spring創(chuàng)建Bean的過程其實很簡單,大致分兩個步驟:

  1. 創(chuàng)建Bean的定義信息BeanDefinition,包含Bean的類型,名稱等信息,注冊到Bean定義工廠中。
  2. 根據(jù)Bean定義工廠中的Bean定義信息,創(chuàng)建出Bean實例。

上面的兩個過程中在通常在SpringBoot啟動的過程中就完成,SpringBoot啟動的時候,會調(diào)用容器的refresh(), 其中在invokeBeanFactoryPostProcessors(beanFactory)方法中創(chuàng)建并注冊BeanDefinition, 在finishBeanFactoryInitialization()方法中創(chuàng)建Bean實例對象。

圖片圖片

創(chuàng)建注冊BeanDefinition

  1. @Component注解

被Compoent注解的的類會被Spring中的ConfigurationClassPostProcessor類處理,創(chuàng)建出對應的BeanDefinition,然后注冊到BeanDefinitionRegistry中,具體流程如下圖所示。

圖片圖片

被@Component注解的類User會被掃描到,生成一個名字是user的BeanDefinition,然后注冊到BeanDefitionRegistry中,如下圖所示:

圖片圖片

  1. @EnableConfigurationProperties注解

注解@EnableConfigurationProperties源碼中import了EnableConfigurationPropertiesRegistrar類,那么它是在什么階段創(chuàng)建出BeanDefinition呢?

圖片圖片

最終配置了@EnableConfigurationProperties(User.class)中被獲取,創(chuàng)建出name為my.user-com.alvinlkk.bean.User的BeanDefinition,如下圖所示。

圖片圖片

而且@Component的順序是優(yōu)先于@EnableConfigurationProperties的。

創(chuàng)建Bean對象

現(xiàn)在BeanDefinitionBean定義信息已經(jīng)有了,Spring就可以根據(jù)這些信息創(chuàng)建出Bean對象實例了,這一個過程是在finishBeanFactoryInitialization()方法中進行的,我們這里重點關注下@Autowird方法是如何進行裝配的。

  1. AbstractApplicationContext#refresh(): 初始化容器
  2. AbstractApplicationContext#finishBeanFactoryInitialization(): 初始化Bean入口
  3. DefaultListableBeanFactory#preInstantiateSingletons():預先初始化單例Bean
  4. DefaultListableBeanFactory#getBean(): 調(diào)用getBean()創(chuàng)建Bean實例
  5. AbstractBeanFactory#doGetBean():getBean()最終調(diào)用的方法
  6. AbstractAutowireCapableBeanFactory#createBean(): 創(chuàng)建Bean實例入口
  7. DefaultListableBeanFactory#determineAutowireCandidate():選擇使用哪個候選的Bean

圖片圖片

根據(jù)類型匹配到Bean有多個的情況,會調(diào)用determineAutowireCandidate()方法進一步去根據(jù)name匹配bean。

總結(jié)

所以對于配置注解ConfigurationProperties的類不要使用使用@Component注解讓Spring管理,更推薦的做法是使用@EnableConfigurationProperties注解進行裝載。

責任編輯:武曉燕 來源: JAVA旭陽
相關推薦

2023-11-19 22:31:00

內(nèi)存程序

2020-05-22 18:16:57

數(shù)據(jù)泄露網(wǎng)絡安全互聯(lián)網(wǎng)

2020-09-02 08:09:10

攻擊防御Shiro

2019-01-03 15:10:40

JVM安全資源

2023-01-05 08:12:11

分層應用代碼

2010-06-04 10:46:18

同事上司

2021-02-24 14:01:13

微服務開發(fā)框架

2018-07-27 17:28:37

人工智能機器學習AI

2022-10-27 11:46:48

ConfiguratValuespring

2015-09-30 10:34:39

容器永久性存儲Docker

2023-10-16 11:12:29

2020-12-11 08:04:22

SpringAOPBean

2022-06-23 10:47:57

Spring容器工具

2025-02-28 09:34:11

前端參數(shù)方式

2015-05-15 17:29:13

.Netxp系統(tǒng)如何解決

2024-05-28 07:55:31

SpringBean用域

2023-11-03 08:18:59

PostgresMySQL

2019-07-15 16:00:24

Docker架構(gòu)容器

2019-07-15 10:00:53

DockerJava容器

2025-03-11 09:00:00

Spring依賴注入Java
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品一区二区三区四区 | 日韩美女在线看免费观看 | 国产精品久久久久久久久免费 | 国产精品一区二 | 狠狠的干狠狠的操 | 九九国产在线观看 | 超碰av在线| 涩涩片影院 | 免费观看一级毛片 | 91中文字幕在线 | 国产精品一区二区在线 | 亚洲一区二区三区四区五区午夜 | 在线久草| 在线观看黄色电影 | 97精品国产 | 国产成人精品a视频一区www | 日韩无 | h视频免费在线观看 | 亚洲成人一区 | 国内激情av片 | www久久久| 欧美综合国产精品久久丁香 | 国产精品日产欧美久久久久 | 国产精品免费一区二区三区四区 | 影音先锋中文字幕在线观看 | 中文字幕一区二区三区在线观看 | 狠狠干美女 | 亚洲精品www久久久久久广东 | av在线免费网站 | 久久噜噜噜精品国产亚洲综合 | 午夜一区二区三区在线观看 | 伊人网伊人网 | 久久网亚洲 | 美女黄网站 | 九色porny自拍视频 | 亚洲欧美视频 | 亚洲精品一区久久久久久 | 超碰成人免费 | 亚洲v区| 亚洲人成在线播放 | 精精精精xxxx免费视频 |