- Bean 定义实质上是创建一个或多个对象的方法。当被访问时,容器将查看命名 bean 的配置,并使用该 bean 定义封装的配置元数据(xml配置)来创建 (或获取) 实际对象
- 如果使用基于 XML 的配置元数据,则可以在 <bean/> 元素的 class 属性中指定要实例化的对象的类型 (或类)。通常,此 class 属性 可以通过以下两种方式之一使用 Class 属性:
- 在容器本身通过反射性地调用其构造函数直接创建 Bean 的情况下,指定要构造的 Bean 类,这在某种程度上等效于 new 运算符的 Java 代码。
- 指定包含被调用以创建对象的 static 工厂方法的实际类,容器将在类上调用 static 工厂方法以创建 Bean。从 static 工厂方法的调用返回的对象类型可以是同一类,也可以是完全不同的另一类。
- 在 Spring 中 bean 的实例化有三种方法
实例化方法 |
说明 |
构造函数实例化 |
通过无参构造函数创建bean |
静态工厂方法实例化 |
通过指定当前对象的静态方法,从静态方法中返回工厂对象的实例 |
实例工厂方法实例化 |
先将包含相关的方法的对象实例化,通过引用已实例化的类中方法,返回工厂对象的实例 |
注
- 如果要为内部类的( static 嵌套类)配置 Bean 定义,则必须使用嵌套类的二进制名称。例如,如果在 com.example 包中有一个名为 SomeThing 的类,并且此 SomeThing 类具有一个名为 OtherThing 的 static 嵌套类,则 Bean 定义上 class 属性的值需要使用$ 字符以将嵌套的类名与外部类名分开,即为 com.example.SomeThing$OtherThing
构造函数实例化
- 当通过构造方法创建一个 bean 时,所有普通类都可以被 Spring 使用并与之兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式进行编码。只需指定 bean 类就足够了。
示例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>
</beans>
注
用于该特定 bean 的 IoC 的类型,可能需要无参构造函数
静态工厂方法实例化
- 定义使用静态工厂方法创建的 bean 时,使用 class 属性来指定包含 static 工厂方法的类,并使用名为 factory-method 的属性来指定工厂方法本身的名称。此方法调用后返回一个活动对象,该对象随后将被视为已通过构造函数创建。这种 bean 定义的一种用法是在旧代码中调用 static 工厂。
示例
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="clientService" class="examples.ClientService" factory-method="createInstance"/>
</beans>
- ClientService.java
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
实例工厂方法实例化
- 与通过静态工厂方法实例化类似,使用实例工厂方法实例化从容器中调用现有 bean 的非静态方法以创建新 bean
- 要使用实例工厂方法实例化,需要在 factory-bean 属性中,在当前 (或父容器或祖先容器) 中指定包含要创建该对象的实例方法的 bean 的名称。使用 factory-method 属性设置工厂方法本身的名称。
示例
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
<!-- inject any dependencies required by this locator bean -->
</bean>
<!-- the bean to be created via the factory bean -->
<bean id="clientService"
factory-bean="serviceLocator"
factory-method="createClientServiceInstance"/>
</beans>
- DefaultServiceLocator.java
public class DefaultServiceLocator {
private static ClientService clientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
- 一个工厂类也可以包含多个工厂方法
示例
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<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"/>
</beans>
- DefaultServiceLocator
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;
}
}