Spring IOC 容器管理一个或多个 bean。这些 bean 是使用你提供给容器的配置元数据创建的(例如,以 XML<bean/>
定义的形式)。
在容器本身中,这些 Bean 定义被表示为BeanDefinition
对象,其中包含(除其他信息外)以下元数据:
-
包限定类名称:通常是正在定义的 Bean 的实际实现类。
-
Bean 行为配置元素,它说明 Bean 在容器中应该如何表现(作用域、生命周期回调,等等)。
-
引用 Bean 完成其工作所需的其他 bean。这些引用也被称为协作者或依赖项。
-
在新创建的对象中设置的其他配置设置——例如,池的大小限制或在管理连接池的 Bean 中使用的连接数量。
Class | 实例化类名 |
Name | 命名Bean |
Scope | Bean的作用域 |
Constroctor Argument | 构造注入 |
Properties | Set注入 |
Autowiring mode | 自动装配模式 |
Lazy initialization mode | 懒加载模式 |
Initialization method | 初始化方法 |
Destruction method | 销毁方法 |
命名Bean
每个 Bean 具有一个或多个标识符。在承载 Bean 的容器中,这些标识符必须是唯一的。 Bean 通常只有一个标识符。但是,如果它需要多个,那么额外的一个可以被视为别名。
例如:
id和name同为标识符,没有优先级。
在同一个bean中id标识符命名可与name标识符命名相同。
<bean class="Entity.Address" id="address" name="address">
<property name="address" value="hunan"/>
</bean>
在不同bean中已存在的标识符命名不可相同。
<bean class="Entity.Address" id="address">
<property name="address" value="hunan"/>
</bean>
<bean class="Entity.Address" name="address">
<property name="address" value="hunan"/>
</bean>
<bean class="Entity.Address" name="address">
<property name="address" value="hunan"/>
</bean>
<bean class="Entity.Address" name="address">
<property name="address" value="hunan"/>
</bean>
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'address' is already used in this <beans> element
Offending resource: class path resource [ApplicationContext.xml]
id属性精确指定一个ID,可在其他bean中进行引用。
name属性可以指定多个别名,在name属性中使用逗号(,)、分号(;)、空格符将别名分割。
<bean id="address" class="Entity.Address" name="address2,address3,address4">
<property name="address" value="hunan"/>
</bean>
也可以使用alias标签进行别名操作,alias标签只能起一个别名。
<alias name="address" alias="address2" />
Bean的实例化
Bean 定义本质上是用于创建一个或多个对象的配方。容器在被请求时查看命名 Bean 的配方,并使用由该 Bean 定义封装的配置元数据来创建(或获取)实际对象。
如果使用基于 XML 的配置元数据,则可以在<bean/>
元素的class
属性中指定要实例化的对象类型(或类)。这个class
属性(在内部,它是Class
实例上的Class
属性)通常是强制的。(有关异常,请参见通过使用实例工厂方法实现实例化和Bean Definition Inheritance。)你可以通过以下两种方式之一使用Class
属性:
-
通常,在容器本身通过反射地调用其构造函数直接创建 Bean 的情况下,指定要构造的 Bean 类,这在某种程度上相当于使用
new
操作符的 爪哇 代码。 -
要指定包含用于创建对象的
static
工厂方法的实际类,在容器在类上调用static
工厂方法以创建 Bean 的较不常见的情况下。调用static
工厂方法返回的对象类型可以是同一个类,也可以完全是另一个类。
嵌套类实例化
如果你希望为嵌套类配置 Bean 定义,那么你可以使用嵌套类的二进制名称或源名。
例如,如果在
com.example
包中有一个名为SomeThing
的类,而这个SomeThing
类有一个名为static
的嵌套类,它们可以用美元符号($
)或圆点(.
)分隔。因此,在 Bean 定义中,class
属性的值将是com.example.SomeThing$OtherThing
或com.example.SomeThing.OtherThing
。嵌套类
类Class1是外部类,而类Class2是静态嵌套类。
public class Class1 { static class Class2 { public void func() { System.out.println("This is a static nested class"); } } public static void main(String args[]) { Class1.Class2 obj = new Class1.Class2(); obj.func(); } }
无参构造实例化(默认)
当通过构造函数方法创建 Bean 时,所有普通类都可由 Spring 使用并与 Spring 兼容。也就是说,正在开发的类不需要实现任何特定的接口,也不需要以特定的方式进行编码。只需指定 Bean 类就足够了。然而,根据你为该特定 Bean 使用的 IOC 类型,你可能需要一个默认(空)构造函数。
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
静态工厂方法的实例化
在定义使用静态工厂方法创建的 Bean 时,使用class
属性指定包含static
工厂方法和一个名为factory-method
的属性的类,以指定工厂方法本身的名称。你应该能够调用这个方法(使用可选参数,如后面所述)并返回一个活动对象,随后将其视为通过构造函数创建的对象。 Bean 这样的定义的一种用途是在遗留代码中调用static
工厂。
下面的 Bean 定义指定通过调用工厂方法来创建 Bean。该定义没有指定返回对象的类型(类),只指定了包含工厂方法的类。在本例中,createInstance()
方法必须是静态方法。下面的示例展示了如何指定工厂方法:
XML配置:
<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;
}
}
实例工厂方法实现实例化
与通过静态工厂法的实例化类似,使用实例工厂方法的实例化从容器调用现有 Bean 的非静态方法来创建新的 Bean。要使用此机制,将class
属性保留为空,并在factory-bean
属性中,指定当前(或父容器或祖先容器)中的 Bean 的名称,该容器包含将被调用以创建对象的实例方法。使用factory-method
属性设置工厂方法本身的名称。下面的示例显示了如何配置这样的 Bean:
XML配置:
<!--工厂 bean,其中包含一个名为 createInstance() 的方法 -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!--注入此定位器 Bean 所需的任何依赖项 -->
</bean>
<!--通过工厂 bean 创建的 bean -->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
Java块:
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
一个工厂类也可以包含多个工厂方法,如下例所示:
XML配置:
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!--注入此定位器 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;
}
}