每个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.介绍
- 七、编程语言