快速目录
- 1 bean的含义
- 2 bean的命名
- 3 bean的实例化
- 4 参考资料
在Spring中,对象包装成Bean,供IOC容器使用。Spring的Beans组件已经明确Bean的定义和Bean的解析,我们的关注点是Bean的创建。在学习Bean的创建之前,先简单了解下Bean的含义和命名。
1 Bean的含义
Bean这个概念是随着Spring框架而出来的。早在1996年,有JavaBean这个概念,后来因为JavaBean太简易不能满足复杂运用程序的要求,因此1998年提出EJB(Enterprise JavaBean)这个概念,后来又因为EJB太过复杂,因此随着Spring框架提出Bean这个概念。详细的演变过程可以看下面参考资料。
那么Bean到底是什么?简单的说,被IOC容器管理的对象称之为Bean,反之没有被容器管理的对象不能称之为Bean,而是一个纯粹的对象(可以思考下这里对象和bean有什么区别?)。
那么如何判断对象是否被IOC容器管理?IOC容器管理的bean又从何而来?
这两个问题的答案藏在bean的配置和初始化中。详细看第三小节。
2 Bean的命名
bean的命名是指给bean声明一个标识符,bean标识符的作用在于为某个bean命名,定义全局(容器内)唯一标识符,方便区别于其他bean,便于在程序中获取该bean。这里的标识符可以用id来表示,也可以用name表示,可以用id和name一起表示,也可以不用id和name来表示。下面分别讨论不同情况下bean的命名方式:
2.1 不声明标识符的命名方式
通过xml配置文件实现:
<!-- 不指定标识符声明bean class表示全路径类名 -->
<bean class="com.syx.chapter1.HelloApiImp"></bean>
这种命名方式的特点:
- 代码中通过getBean<Class<>>获取该bean,参数为bean的class类;
- 生成的对象是单例;
我很好奇没有命名的bean会如何标识自己,于是尝试调用bean的toString()方法,并打印到控制台,结果为:
com.syx.chapter1.HelloApiImp@12843fce
这是很常见的类名加对象哈希码,不能说是它的标识符。后来在错误信息中无意发现Spring给他的默认名:
com.syx.chapter1.HelloApiImp#0
如果配置文件中有多个这样的bean,则产生的bean命名为数字相应+1。
即:com.syx.chapter1.HelloApiImp#1,com.syx.chapter1.HelloApiImp#2
所以getBean(Class<>)方法应该是按照默认命名方式去查找的,当有多个该class类的对象时,该方法获取bean时会报错。
2.2 id标识符的命名方式
通过XML配置文件实现:
<!-- id 表示bean的名字,class表示全路径类名 -->
<bean id="hello" class="com.syx.chapter1.HelloApiImp"></bean>
这种命名方式的特点:
- 代码中通过getBean(String arg0,Class<> arg1)获取bean,arg0为id,arg1为类名;
PS:思考一下,此时的bean是否可以通过getBean(class<>)方式获取?如果2.1小节的bean和此时的bean同时存在,又是否可以通过getBean(class<>)获取呢?如果不行,2.1小节中的bean该如何获取? - id在这个配置文件中必须唯一;
- id后面只能跟一个值;
2.3 name标识符的命名方式
通过XML配置文件实现:
<!-- name 表示bean的名字,class表示全路径类名 -->
<bean name="hello1" class="com.syx.chapter1.HelloApiImp"></bean>
特点跟2.2小节一样。只有最后一点不同,即name后面可以跟多个名字,名字之间通过分号、空格或者逗号隔开,这里只有第一个name名为标识符,后面的都为别名,表示如下:
<bean name="hello1 ,hello1_1 ,hello1_2" class="com.syx.chapter1.HelloApiImp