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-methoddestory-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;
    }
}
posted @ 2023-01-31 14:32  小张同学哈  阅读(208)  评论(0)    收藏  举报