透過Spring源碼查看Bean的命名轉換規(guī)則圖文詳解
前言
近期在寫Spring項目的時候,需要通過注解的形式去替代之前直接將Bean存放在Spring容器這種方式,以此來簡化對于Bean對象的操作,但是這樣無法通過準確的Id去獲取到相應的Bean對象了
測試觀察
首先,如果要將指定的對象存放到Spring中,在Spring的配置文件中的掃描包路徑一定不能錯,這樣我們在這個包中所包含的類前加上【五大類注解】,就可以將對象存儲到Spring中的
<content:component-scan base-package="com.spring.demo"></content:component-scan>

然后我便在這個包下寫了個UserController 類,并且加上了【@Controller】注解,此時Spring在加載的時候就會存儲改對象
@Controller
public class UserController {
public void SayHello(){
System.out.println("do SayHello()");
}
}此時看到,我在App類中去獲取到了這個Bean對象,而且使用的是【名稱 + 類名】的形式,這種形式就可以防止Spring中存儲多個Bean對象而造成的沖突問題
但是呢,我就卡在了這里,不知道該去寫什么名稱?因為根本沒有在Spring中寫明Id值

首先我想到的是這個名稱會不會就是類名呢?但是在我進行嘗試之后卻發(fā)現(xiàn)并不是這樣,編譯器報出了異常說No bean named 'UserController' available

然后我又想到了Java的命名規(guī)范是【小駝峰】,一般去通過這個類實例化對象的時候都是將首字母進行一個小寫,其余不變,于是當我使用這個名稱進行傳遞的時候,程序運行就沒有問題了

那我首先猜測它的命名就是這樣規(guī)定的,但是有沒有特例呢?
此時我又去定義了一個類,將其類名取成了兩個大寫字母開頭的,看看這樣子的命名是否還會以【小駝峰】的形式去進行轉換
@Controller
public class SController {
public void SayHello(){
System.out.println("do SayHello()");
}
}但是當我在看運行結果的時候,卻發(fā)現(xiàn)這樣小駝峰的形式似乎行不通了

但是當我在將名稱改回【類名】的時候,卻發(fā)現(xiàn)又可以運行了,這是為什么呢?里面的轉換規(guī)則又是怎樣的?這需要我再去研究一番??

原理探究
通過上面的測試可以看出,Spring對于這個Bean對象的命名轉換是存在一定規(guī)則的,因為【在Spring中,約定大于俗成】
接下去我就通過查看Spring源碼的方式帶讀者來探究一下到底這個Spring內部對于這個Bean的命名轉換規(guī)則是怎樣的,雖然Spring框架的代碼都是開源的,但是要精準地找到對應想要的代碼邏輯可不簡單,需要層層深入地進行探訪
1、首先第一步,我們可以按兩下【shift】鍵,便會跳出IDEA的搜索框,在這個里面你可以去搜尋當前項目中所有的類、接口,以查看它們的內部實現(xiàn)。然后我便發(fā)現(xiàn)了一個類叫做AnnotationBeanNameGenerator,翻譯一下即為【注釋Bean名稱生成器】,那我猜測命名規(guī)范的代碼邏輯可能就在這個類中

2、當我們進入到這個類后,就可以去尋找其對應的方法了,那個方法是和BeanName有關聯(lián)的,首先點擊右側的【結構】我們便可以看到這個類中到底有哪些方法,那一看我們就可以觀察到有generateBeanName()這個方法,點到對應的方法后再進行觀察,便發(fā)現(xiàn)其最后返回時又去調用了一個方法,于是我繼續(xù)按住Ctrl鍵點進去

點進去發(fā)現(xiàn)里面又是一個方法,一些復雜的邏輯其實就是以這樣一種嵌套的形式進行的,各個類、接口之間的方法調來調去

然后看到這是下面的這個方法buildDefaultBeanName()生成默認Bean名稱

最后的話我們看到它在return的時候似乎又通過一個類名去調用了一個方法,然后傳入了這個ClassName,那我繼續(xù)點進去后就發(fā)現(xiàn)我似乎已經(jīng)不處于Spring框架的源碼中了,而是來到了JDK中
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char[] chars = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}我們可以點擊右上角的這個按鈕【選擇打開的文件】去找到這個類所對應的位置

最后我這邊順騰摸瓜地去查找就看到這個類是java.deskop包下的一個類,那么我們在查看Spring源碼的時候最終還是來到了JDK下,這個可以說明一點:Bean的命名并不是亂取的,而是使用JDK的一個命名標準去進行命名的

然后我們就可以去看看JDK中對于命名的規(guī)范到底是怎樣的??
可以看到很明顯的這里是有兩種情況,若是首字母和第二個字母都是大寫的話,那就返回原來的名稱;第二種情況則是將字符串首先轉換成了字符數(shù)組,然后再將第一位變成小寫
那看到這里的話其實我已經(jīng)是明白了,原來Spring對于Bean的這個命名規(guī)則是這樣的

總結一下
最后的話我們來總結一下本次查看源碼的收獲吧??
通過查看Spring的源碼我們進入到了JDK中,經(jīng)過代碼的閱讀將Bean的命名轉換總結了以下兩點
默認情況:使用原類名首字母小寫就能讀取到Bean對象特例:如果首字母和第二字母都是大寫的情況下,那么Bean名稱就是原類名
在學習Spring框架的過程中,初學者難免會遇到不理解的地方,因為Spring是一個IoC容器,會通過DI依賴注入的形式幫我們自動地去管理對象,所以內部的細節(jié)便不得而知,但我們可以通過【閱讀源碼】的方式來進行理解,去看看大佬是怎么思考的??
到此這篇關于透過Spring源碼查看Bean的命名轉換規(guī)則的文章就介紹到這了,更多相關Bean命名轉換規(guī)則內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
javax.validation.constraints如何校驗參數(shù)合法性
本文將深入探討javax.validation.constraints的基本用法和高級應用,幫助讀者更好地理解和運用這個強大的校驗框架,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
Eclipse中改變默認的workspace的方法及說明詳解
eclipse中改變默然的workspace的方法有哪幾種呢?接下來腳本之家小編給大家介紹Eclipse中改變默認的workspace的方法及說明,對eclipse改變workspace相關知識感興趣的朋友一起學習吧2016-04-04
java web實現(xiàn)網(wǎng)上手機銷售系統(tǒng)
這篇文章主要為大家詳細介紹了java web實現(xiàn)網(wǎng)上手機銷售系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08
springcloud config配置讀取優(yōu)先級過程詳解
這篇文章主要介紹了springcloud config配置讀取優(yōu)先級過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-09-09

