在 Spring中,id 和 name 命名 Bean 有什么區(qū)別?
首先,讓我們來看下Spring XML配置方式,id和name是如何定義Bean的:
<!-- 用id定義 -->
<bean id="userService" class="com.example.UserService"/>
<!-- 用name定義 -->
<bean name="userService" class="com.example.UserService"/>
接著,我們看一個(gè)注解方式:
// 注解方式
@Service("userService")
public class UserService {}
那么,問題來了:注解中的@Service("userService")相當(dāng)于 XML中的 id還是 name?
這篇文章,我們來聊一聊。
1. 歷史背景
在早期的Spring版本(1.x時(shí)代):
- id屬性:必須符合 XML ID規(guī)范(不能有特殊字符,不能以數(shù)字開頭等)
- name屬性:更靈活,可以用各種字符,還能定義多個(gè)別名
這就導(dǎo)致很多開發(fā)者因?yàn)?XML規(guī)范限制不得不使用name。
但是!在Spring 3.1之后,id屬性不再受XML ID規(guī)范約束了,現(xiàn)在它和name在靈活性上已經(jīng)平起平坐了。
2. 原理剖析
本質(zhì)相同:無論是id還是name,最終都會(huì)變成 Bean的標(biāo)識(shí)符(identifier)。
特殊之處:
- id:一個(gè) Bean只能有一個(gè)id
- name:可以定義多個(gè),用逗號(hào)/分號(hào)/空格分隔,相當(dāng)于給Bean起別名,
<bean name="userService,userManager,userApi" class="com.example.UserService"/>
查找順序:當(dāng)使用getBean()時(shí),Spring會(huì)先查id,再查 name
3. 如何獲取 bean?
場景1:簡單Bean定義
// 注解方式
@Service("userService") // 這相當(dāng)于xml中的id還是name?
public class UserService {}
對于@Service("xxx")中的名稱既會(huì)作為id,也會(huì)作為 name注冊!這個(gè)也回到了我們文章開頭的問題。
場景2:需要?jiǎng)e名的情況
<bean id="mainDataSource" name="primaryDB,defaultDB" class="com.example.DataSource"/>
這時(shí)候用 name定義別名就很方便,代碼中可以根據(jù)不同場景使用不同名稱獲取同一個(gè)Bean。
場景3:帶有特殊字符的Bean名
<bean name="/api/user" class="com.yuanjava.UserController"/>
雖然現(xiàn)在 id也支持特殊字符了,但看到name="/api/user"這樣的寫法,是不是更符合咱們的直覺?
4. id和name有區(qū)別嗎?
通過上面的分析,你覺得id和name命名Bean在性能上會(huì)有差異嗎?
答案是:幾乎沒有區(qū)別!因?yàn)镾pring內(nèi)部會(huì)把它們統(tǒng)一處理成標(biāo)識(shí)符,選擇id或name不會(huì)影響應(yīng)用性能。
經(jīng)過這么多年的踩坑,我的建議是:
- 默認(rèn)使用id:因?yàn)樗Z義化,表示唯一標(biāo)識(shí)
- 需要?jiǎng)e名時(shí)加上name:兩者可以共存!
<bean id="userService" name="userManager,userApi" class="com.example.UserService"/>
- 團(tuán)隊(duì)統(tǒng)一規(guī)范:比選擇哪個(gè)更重要!
5. 總結(jié)
本文,我們分析了id和name命名的歷史,區(qū)別,以及如何在應(yīng)用中使用它們:
- 如果你的Bean需要一個(gè)明確的、唯一的標(biāo)識(shí),請用id命名Bean
- 如果需要靈活性、多個(gè)名稱,請用name命名Bean
- 其實(shí)在Spring的現(xiàn)代版本中,它們的差別已經(jīng)很小了,最關(guān)鍵是保持一致性
好的命名是成功的一半,在 Spring世界里,id和name就像你的左右手,關(guān)鍵是要知道什么時(shí)候用哪只!