<beans.../>元素是Spring配置文件的根元素,该元素可以指定如下属性。
Ø default-lazy-init:指定该<beans.../>元素下配置的所有Bean默认的延迟初始化行为。
Ø default-merge:指定该<beans.../>元素下配置的所有Bean默认的merge行为。
Ø default-autowire:指定该<beans.../>元素下配置的所有Bean默认的自动装配行为。
Ø default-autowire-candidates:指定该<beans.../>元素下配置的所有Bean默认是否作为自动装配的候选Bean。
Ø default-init-method:指定该<beans.../>元素下配置的所有Bean默认的初始化方法。
Ø default-destroy-method:指定该<beans.../>元素下配置的所有Bean默认的回收方法。
提示:
<bean.../>元素是<beans.../>元素的子元素,<beans.../>元素可以包含多个<bean.../>子元素,每个<bean.../>子元素定义一个Bean,每个Bean对应Spring容器里的一个Java实例。
定义Bean时,通常需要指定两个属性。
Ø id:确定该Bean的唯一标识符,容器对Bean管理、访问,以及该Bean的依赖关系,都通过该属性完成。Bean的id属性在Spring容器中应该是唯一的。
Ø class:指定该Bean的具体实现类,这里不能是接口。Spring容器必须知道创建Bean的实现类,而不能是接口。通常情况下,Spring会直接使用new关键字创建该Bean的实例,因此,这里必须提供Bean实现类的类名。
id属性是容器中Bean的唯一标识,这个id属性必须遵循XML文档的id属性规则,因此有一些特殊要求,例如不能以“/”等特殊符号作为属性值。但在某些特殊时候,Bean的标识必须包含这些特殊符号,此时可以采用name属性,用于指定Bean的别名,通过访问Bean别名也可访问Bean实例。
- <?xml version="1.0" encoding="GBK"?>
- <!-- Spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束 -->
- <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://www.springframework.org/schema/beans"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <!-- 定义第一个Bean实例bean1,对应的实现类为lee.Test1 -->
- <bean id=”bean1” class=”lee.Test1”/>
- <!-- 定义第二个Bean实例bean2,对应的实现类为lee.Test2 -->
- <bean id=”bean2” class=”lee.Test2”/>
- </beans>
Spring容器集中管理Bean的实例化,Bean实例可以通过BeanFactory的getBean(String beanid)方法得到,BeanFactory变成简单工厂模式里的工厂,程序只需要获取BeanFactory引用,即可获得Spring容器管理全部实例的引用。程序不需要与具体实例的实现过程耦合。大部分Java EE应用里,应用在启动时,会自动创建Spring容器,组件之间直接以依赖注入的方式耦合,甚至无须主动访问Spring容器本身。
当我们在配置文件中通过<bean id="xxx" class="lee.XxxClass"/>方法配置一个Bean时,这样要求该Bean实现类必须有一个无参数的构造器,因此Spring
如果在配置文件中通过构造注入来创建Bean,配置代码如下:
上面的粗体字代码相当于让Spring调用如下代码:
bean1 = new lee.Test1("hello" , "23"); //①
由于Spring本身提供了功能强大类型转换机制,因此如果lee.Test1只包含一个Test1(String , int)构造器,那么上面的粗体字配置文件相当于让Spring执行如下代码:
bean1 = new lee.Test1("hello" , 23); //②
这就有了一个问题,如果lee.Test1类既有Test1(String ,String)构造器,又有Test1(String ,int)构造器,那么上面的粗体字配置文件到底让Spring执行哪行代码呢?答案是①号代码,因为此时的配置还不够明确:对于<constructor value="23"/>,Spring只能解析出一个"23"字符串,但它到底需要转换为哪种数据类型——从配置文件中看不出来,只能是根据lee.Test1的构造器来尝试转换。
除了可以为<bean.../>元素指定一个id属性之外,还可以为<bean.../>元素指定name属性,用于为Bean实例指定别名。
<bean.../>元素的id属性具有唯一性,而且是一个真正的XML ID属性,因此其他XML元素在引用该id时,可以利用XML解析器的验证功能。
由于XML规范规定了XML ID标识符必须由字母和数字组成,且只能以字母开头,但在一些特殊情况下(例如与Struts1整合过程中),我们必须为控制器Bean指定特殊标识名,此时就必须为控制器Bean指定别名。
如果需要为Bean实例指定多个别名,可以在name属性中使用逗号、冒号或者空格来分隔多个别名,后面通过任一别名即可访问该Bean实例。
在一些极端的情况下,程序无法在定义Bean时就指定所有的别名,而是需要在其他地方为一个已经存在的Bean实例指定别名,则可使用<alias.../>元素来完成,该元素可指定如下两个属性。
Ø name:该属性指定一个Bean实例的标识名,表明将为该Bean实例指定别名。
Ø alias:指定一个别名。
如以下代码示例:
<alias name="person" alias="jack"/>
<alias name="jack" alias="jackee"/>
在默认情况下,当Spring创建ApplicationContext容器时,Spring会自动预初始化容器中所有的singleton实例,如果我们不想让Spring容器预初始化某个singleton Bean,则可为该<bean.../>元素增加lazy-init属性,指定该属性为true,则Spring不会预初始化该Bean实例,如下面的配置文件所示。
<bean id="bean2" class="lee.Test2" lazy-init="true"/>
- <?xml version="1.0" encoding="GBK"?>
- <!-- Spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束 -->
- <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://www.springframework.org/schema/beans"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
- <!-- 定义第一个Bean实例bean1,对应的实现类为lee.Test1 -->
- <bean id=”bean1” class="lee.Test1">
- <constructor-arg value="hello"/>
- <constructor-arg value="23"/>
- </bean>
- </beans>
底层相当于调用了如下代码:
- xxx = new lee.XxxClass()
下面给出包含两个Bean定义的简单配置文件。
<beans.../>元素上面所能指定的属性都可以在每个<bean.../>子元素中指定——将属性名去掉default即可。区别是:为<bean.../>元素指定这些属性,只对特定Bean起作用;如果在<beans... />元素上指定这些属性,这些属性将会对<beans.../>包含的所有Bean都起作用。类似的是,当二者所指定的属性不一致时,<bean.../>上指定的属性会覆盖<beans.../>上指定的属性。