Naming beans
每个bean可以有一个或多个标识符。这些标识符在持有bean的容器必须是唯依的。一个bean通常只具有一个标识符,但如果其需要超过一个,额外的标识符可以被认为是别符。
在基于XML配置的元信息中,你使用id或name属性来指定bean的标识符。id属性允许你显式的指定一个id。习惯上这些名字是由数字和字母组成的('myBean', 'fooService'),但也可以包含特殊字符。如果你想给bean引入另外的别名,你可以指定他们的name属性,由逗号(,), 分号(;), 或空格字符分隔。作为历史的注意点,在Spring3.1之前,id属性由xsd:ID类型定义,限制可用的字符。在3.1,其由xsd:string类型定义。注意bean的id的唯依性还会被容器强制要求,而不在是XML的解析器。
给bean提供名字和id不是必须的。如果没有显示的给bean提供name或id,容器会为其生成一个唯依的名字。然而,如果你想通过名字引用bean,如通过ref元素或Service Locator风格的寻找,你必须提供名字。不提供bean的名字的动机是使用inner bean或自动注入收集机制(autowiring collaborators).
Bean的命名习惯
当给bean命名时使用Java给字段命名的标准的习惯,这是,bean的名字以一个小写的字母开始,从小写字母以后以驼峰命名。例如这样的名字将是(没有单引号)'accountManager', 'accountservice', 'userDao', 'loginController,等等'
全用习惯的命名风格使你的配置容易阅读和理解,如果你使用spring AOP当你为一个与名字相关联的bean提供通知提供很大的帮助
在classpath的组件扫描中,Spring为未命名的组件成生bean的名字,遵守上面的规则:额外的,采用简单的类名并把类名的初始字符转换为小写。然而,特殊情况是(不经常)当名字超过一个字符并且第一个和第二个字符都是大写时,原始的名字被保留。这与java.beans.Introspector.decapitalize(Spring在这使用的)定义的规则一致
在bean定义外给bean提供别名
在bean定义中,你可以给bean提供超过一个的名字,通过结合使用指定id属性提供一个名字,指定name属性提供任意数量的名字。These names can be equivalent aliases to the same bean, 在一些情况下是很有用的,例如允许应用中的每个组件使用组件自身指定的bean名字来引用同一个bean。
然而,特别的是bean真正定义的所有别名不总是够用的。一些时候,我们渴望在bean定义外来为一个bean引入别名。这在大型的系统中(配置系统分割在每个子系统中)是常见的case,每个子系统拥有其自身的对象定义。在基于XML配置的元信息中,你可以使用<alias/>元素来完成此项任务。
<alias name="fromName" alias="toName"/>
在这种情境下,在同一个容器中名字为fromName的bean,在使用别名定义后,也可以通过toName来引用。
例如,在子系统A的配置元信息中可能使用subsystemA-dataSource来引用一个连接池。在子系统B的配置元信息中可能使用subsystemB-dataSource来引用一个连接池。主系统使用myApp-dataSource来引用连接池,当这些子系统与主应用组合时。使这三个名字引用同一个对象,你需要在MyApp的配置元信息中添加下面的别名定义:
<alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/>
<alias name="subsystemA-dataSource" alias="myApp-dataSource"/>
现在每个组伯和主应用通过不同的名字来引用同一个连接池,并确保不会与别的定义冲突(有效的创建一个命名空间),还保证他们引用了同一个相同的bean.
Java-configuration
如果你使用Java配置,@Bean注解可以用来提供别名,参阅7.12.3章,“Using the @Bean annotation”获取更详细的信息。
自己的总结
当在bean定义中,bean的name不唯一,会抛出异常,应用无法启动
例:
<bean id="love3" name="love" class="com2.jianglei.bean.Love3"/>
<bean id="love2" name="love" class="com2.jianglei.bean.Love2"/>
启动应用时
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Bean name 'love' is already used in this <beans> element
而别名定义重复,不会抛出异常,后者会覆盖前者的定义
例:
<bean id="love3" class="com2.jianglei.bean.Love3"/>
<bean id="love2" class="com2.jianglei.bean.Love2"/>
<alias name="love3" alias="love"/>
<alias name="love2" alias="love"/>
public class XmlApp5 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:com2/jianglei/spring-context4.xml");
Object love = context.getBean("love");
System.out.println(love.getClass());
}
}
/*
output:class com2.jianglei.bean.Love2
/*