Spring之Bean的配置
Bean的配置
在Spring的配置文件applicationContext.xml中配置如下Bean即可将Bean注入到IOC容器中。
<bean class="com.zzvcom.bean.Person" >
</bean>
id属性
在Spring容器中不能重复,默认值为bean的权限定类型+#+数字下标,上例中bean的id为`com.zzvcom.bean.Person#0`,如果同时声明两个:
<bean class="com.zzvcom.bean.Person" ></bean>
<bean class="com.zzvcom.bean.Person" ></bean>
则第一个Bean的id为com.zzvcom.bean.Person#0,第二个bean的id为com.zzvcom.bean.Person#1。
name属性
为bean指定名称,名称在Spring容器中对于不同的Bean也不能重复。如:
<bean id="p1" name="p3" class="com.zzvcom.bean.Person"></bean>
<bean id="p2" name="p3" class="com.zzvcom.bean.Person" ></bean>
将会报错:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'p3' is already used in this <beans> element
Offending resource: class path resource [ApplicationContext.xml]
可以指定多个,使用空格、分号、逗号分隔均可.
<bean name="p2;p3" class="com.zzvcom.bean.Person" ></bean>
如果未指定Bean的id,Spring将使用第一个name属性作为bean的id。上例中,Spring将p2作为id,将p3作为别名。作为ID的name属性依然不能重复。
<bean name="p2;p3" class="com.zzvcom.bean.Person" ></bean>
<bean name="p2;p3" class="com.zzvcom.bean.Person" ></bean>
此时依然会报错:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'p2' is already used in this <beans> element
Offending resource: class path resource [ApplicationContext.xml]
Spring Bean的id生成规则:
1、声明Bean时如果指定了id,则使用该id
2、如果未指定id,则使用第一个name属性作为id,其他name作为bean的别名
3、如果id与name属性均未指定,则使`用全限定类型+#+数字下标`作为该bean的id。
class属性
指定Bean的具体类,由Spring使用反射创建Bean实例时使用。一般情况下Spring使用反射调用Bean的构造方法(`constructor`)初始化Bean实例。Spring支持内部类的情况如:Person类中有一个内部类为Address类,可以使用如下方式指定:
<bean name="address" class="com.zzvcom.bean.Person$Address" ></bean>
autowire属性
指定Spring的自动装配类型。
| 类型 | 说明 |
|---|---|
| no | (默认值)不采用autowire机制.。这种情况,当我们需要使用依赖注入,只能用标签。 |
| byName | 通过属性的名称自动装配。Spring会在容器中查找名称与bean属性名称一致的bean,并自动注入到bean属性中。当然bean的属性需要有setter方法。 |
| byType | 通过类型自动装配。Spring会在容器中查找类(Class)与bean属性类一致的bean,并自动注入到bean属性中,如果容器中包含多个这个类型的bean,Spring将抛出异常。如果没有找到这个类型的bean,那么注入动作将不会执行。 |
| constructor | 通过构造函数的参数类型来匹配。装配过程与byType类似。 |
| default | 采用父级标签(即beans的default-autowire属性)的配置。 |
其中`byType`和`constructor`模式也支持数组和强类型集合(即指定了集合元素类型)。如bean A有个属性定义是List类型,Spring会在容器中查找所有类型为Foo的bean,注入到该属性。记住是Foo,不是List。
另外如果集合是Map集合,那么`Map`的`key`必须是`String`类型,`Spring`会根据`value`的类型去匹配。例如有属性bean A中有一个属性为`Map<String, Foo> p`,容器中有`bean B`和C类型均为`Foo`,那么A实例化完成后,p属性的值为:{"`B的bean id`":B的实例对象,"`C的bean id`":C的实例对象}。
除了可以给单独一个`bean`配置`autowire`属性,我们还可以给某个bean配置文件的标签添加`default-autowire`属性。在标签中指定`default-autowire`属性,那么对于子标签如果设置的`autowire`属性,那么将采用父标签的`default-autowire`属性的模式,如果单独设置了另外的`autowire`属性,则采用自己的模式。
autowire-candidate属性
前面我们说到配置有`autowire`属性的`bean`,Spring在实例化这个bean的时候会在容器中查找匹配的bean进行属性注入,这些被查找的bean我们称为候选bean。bean自身可以决定自己是否可以以作为候选bean。如果bean给自己增加了`autowire-candidate="false"`属性(默认是true),那么容器就不会把这个bean当做候选bean了,即这个bean不会被当做自动装配对象。
同样,标签可以定义`default-autowire-candidate="false"`属性让它包含的所有bean都不做为候选bean。
scope属性
默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域。
| 类型 | 说明 |
|---|---|
| singleton | 在Spring容器中仅存在一个Bean实例 |
| prototype | 每次调用getBean()都会返回一个新的实例 |
| request | 每次HTTP请求都会创建一个新的Bean,仅适用于WebApplicationContext环境中 |
| session | 同一个HTTP SESSION共享一个Bean实例,仅适用于WebApplicationContext环境中 |
| application | 同一个ServletContext共享一个实例,仅适用于WebApplicationContext环境中 |
| websocket | 同一个websocket共享一个实例,仅适用于WebApplicationContext环境中 |
init-method和destory-method属性
Bean的生命周期回调方法。`init-method`在Bean初始化并填充属性完成之后由Spring容器调用,`destory-method`在Bean销毁的最后阶段由Spring容器调用。
lazy-init属性
在默认情况下,Spring容器(`ApplicationContext`)在容器初始化阶段会创建所有的单例(此行为有助于提早发现配置相关的错误)。如果Bean的`lazy-init`属性配置为true,这Spring在容器启动及Bean初始化阶段将不会创建Bean实例,而是在第一次调用`getBean()`方法时才会初始化。值得一提的是,如果一个非`lazy-init`的bean依赖于一个`lazy-init`的bean,那么`lazy-init`的bean也会变成非`lazy-init`以满足依赖关系。
factory-method属性
指示Spring容器使用静态工厂方法实例化Bean。配置了该属性的Bean将不使用`constructor`初始化Bean,而是使用`factory-method`指定的静态方法创建Bean。该`factory-method`必须是`class`属性指定的类的静态方法。`factory-method`必须是无参的。如:
<bean id="clientService" class="examples.ClientService"
factory-method="createInstance"/>
Java代码:
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
Spring将使用`ClientService`的静态方法`createInstance`创建Bean实例。
factory-bean属性
与`factory-method`搭配使用,指示Spring容器使用实例工厂方法初始化Bean。使Spring能够使用`factory-bean`指定的Bean实例中的非静态方法来创建Bean。如:
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
<bean id="accountService"
factory-bean="serviceLocator"
factory-method="createAccountServiceInstance"/>
Java代码:
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
private static AccountService accountService = new AccountServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
public AccountService createAccountServiceInstance() {
return accountService;
}
}
浙公网安备 33010602011771号