多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
每个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)。