每個Bean都有一個或者更多的標識符,這些標識符在容器中是唯一的。一般一個Bean只有一個標識符,如果需要更多的標識符,可以考慮使用別名。
在基于XML的配置元數據中,可以通過`id`或者`name`屬性指定Bean的標識符。`id`屬性允許你明確指定唯一值,通常會以字母和數字的組合來指定標識符的值('myBean','fooService'等等),但是使用特定的字符也是可以的。如果你想為Bean定義別名,可以通過`name`屬性指定,多個別名用逗號、分號或者空格分隔。在Spring的歷史版本記錄中,Spring3.1之前,`id`屬性被定義為`xsd:ID`類型,使得id的取值受到了限制。之后的版本中被定義為`xsd:string`類型,Bean的id屬性的唯一性由容器來強制執行,不在使用XML解析器。
你不需要為Bean顯式提供`id`和`name`屬性值,如果你未提供的話,容器會為Bean生成唯一的name值。然而,如果你要通過其它Bean的`name`屬性來引用Bean,可以通過`ref`屬性或者Service Locator風格查找,這必須提供name。如果想不提供name來完成Bean的引用,可以使用內部Bean和依賴注入合作者([1.4.2.依賴和配置詳情](1.4.2.依賴和配置詳情.md))。
> :-: **Bean的命名約定**
>
> Spring使用的是Java標準的命名規范,也就是以小寫字母開頭的駝峰命名方式。例如 :`accountManager`、`accountService`、 `userDao`、`loginController`等等。命名的一致性使得你的配置更易閱讀和理解。當你使用Spring AOP時,通過指定Bean的name值將通知關聯到對應的Bean也是很有幫助的。
> 在類路徑中進行組件掃描時,Spring會為未命名的Bean生成一個小寫字母開頭的name值。然而,在特殊情況下,如果有多個字符,并且第一個和第二個字符都是大寫,則保留原始大小寫。Spring是通過`java.beans.Introspector.decapitalize`方法來實現的,該實現如下:
>
> ~~~
> public static String decapitalize(String name) {
> if (name == null || name.length() == 0) {
> return name;
> }
>
> //如果類名的第一個和第二個字母都是大寫,直接將類名作為Bean的name值。
> if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
> Character.isUpperCase(name.charAt(0))){
> return name;
> }
>
> //將類名的首字母小寫后作為Bean的name值。
> char chars[] = name.toCharArray();
> chars[0] = Character.toLowerCase(chars[0]);
> return new String(chars);
> }
> ~~~
*****
### **在Bean定義外為其指定別名**
在Bean定義的內部,可以通過將`id`和`name`屬性的組合來使得一個Bean有多個標識符,其中id的值只有一個,name是數量任意的。一個Bean的別名之間都是等價的,這在一些場景下是有用的。比如:在一個應用中,你可以通過Bean的別名來讓每個組件引用公共的依賴。
在定義Bean時指定所有別名往往是不夠的,值得高興的是可以在其它地方指定。這種用法通常出現在將配置拆分在每個子系統的大系統中,每一個子系統都有他自己的一套對象的定義。在基于XML的配置元數據中,你可以使用`<alias/>`來定義別名。
~~~
<alias name="fromName" alias="toName"/>
~~~
在這個例子中,name為`fromName`的bean也被稱為`toName`,其它Bean可以通過`toName`去引用它。
舉個具體的例子:
子系統A在配置元數據中引用了name為`subsystemA-dataSource`的Bean,
子系統B在配置元數據中引用了name為`subsystemB-dataSource`的Bean,當將子系統組合成主系統時,主系統可能會通過name為`myApp-dataSource`的DataSource。為了讓三個name引用的是同一個Bean,你可以在主應用中添加如下別名定義:
~~~
<alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/>
<alias name="subsystemA-dataSource" alias="myApp-dataSource" />
~~~
如此一來,每個組件和主應用都可以通過不同的`name`引用同一個的`DataSource`,也不會和其他Bean的`name`沖突。
> ##### 使用Java配置
> @Bean注解也可以為Bean指定別名,詳情參見:[1.12.3.使用@Bean注解](1.12.3.使用Bean注解.md)。
- ---- 閱讀說明
- 一、核心技術
- 1.IOC容器
- 1.1.IOC 容器和 Bean 簡介
- 1.2.容器概覽
- 1.2.1.配置元數據
- 1.2.2.實例化容器
- 1.2.3.使用容器
- 1.3.Bean概覽
- 1.3.1.Bean的命名
- 1.3.2.實例化Bean
- 1.4.依賴
- 1.4.1.依賴注入
- 1.4.2.依賴配置詳情
- 1.4.5.注入合作者
- 1.4.4.Bean的懶加載
- 1.5.Bean的范圍
- 1.6.自定義Bean的特性
- 1.6.1.生命周期回調函數
- 1.7.繼承Bean定義
- 1.9.基于注解的容器配置
- 1.9.1.@Required
- 1.12.基于Java的容器配置
- 1.12.3.使用@Bean注解
- 1.15.ApplicationContext的附加功能
- 1.15.4.Web 應用中便捷的 ApplicationContext 實例
- 1.16.BeanFactory
- 2.資源
- 2.7.應用上下文和資源路徑
- 3.驗證、數據綁定以及類型轉換
- 3.5.Spring類型轉換
- 3.5.4.ConversionService API
- 5.基于 Spring 的面向切面編程
- 5.8.在 Spring 中使用 AspectJ
- 5.8.1.在 Spring 中使用 AspectJ 注入領域對象
- 二、測試
- 三、數據訪問
- 四、Web應用
- 五、Web響應式編程
- 六、集成
- 4.1.介紹
- 七、編程語言