Spring4.0学习8--通过工厂方法配置bean

通过调用静态工厂方法创建 Bean

调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中. 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节.
要声明通过静态方法创建的 Bean, 需要在 Bean 的 class 属性里指定拥有该工厂的方法的类, 同时在 factory-method 属性里指定工厂方法的名称. 最后, 使用 <constrctor-arg> 元素为该方法传递方法参数.

例:
Car.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.beanfactory;
public class Car {
private String brand;
private double price;
public Car(String brand, double price) {
super();
this.brand = brand;
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Car [brand=" + brand + ", price=" + price + "]";
}
}

StaticCar.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.beanfactory;
import java.util.HashMap;
import java.util.Map;
/*
* 静态工厂方法:直接调用某一个类的静态方法就可以返回 bean 的实例
*/
public class StaticCar {
private static Map<String, Car> cars = new HashMap<String, Car>();
static {
cars.put("玛莎拉蒂", new Car("玛莎拉蒂", 1800000));
cars.put("法拉利", new Car("法拉利", 1800000));
}
// 静态工厂方法
public static Car getCar(String name) {
return cars.get(name);
}
}

beans-factory.xml:

1
2
3
4
5
6
7
8
9
<!-- 通过静态工厂方法来配置bean.注意不是配置静态工厂方法实例,而是配置bean实例 -->
<!--
class:指向静态工厂方法全类名
factory-method:指向静态工厂方法名
constructor-arg:如果工厂方法需要参数,则使用constructor-arg来配置参数
-->
<bean id="car" class="com.beanfactory.StaticCar" factory-method="getCar">
<constructor-arg value="玛莎拉蒂"></constructor-arg>
</bean>

Main.java代码千篇一律,就不写了。

通过调用实例工厂方法创建 Bean

实例工厂方法: 将对象的创建过程封装到另外一个对象实例的方法里. 当客户端需要请求对象时, 只需要简单的调用该实例方法而不需要关心对象的创建细节.
要声明通过实例工厂方法创建的 Bean

  • 在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean
  • factory-method 属性里指定该工厂方法的名称
  • 使用 construtor-arg 元素为工厂方法传递方法参数

示例:
InstanceCarFactory.java:

1
2
3
4
5
6
7
8
9
10
11
public class InstanceCarFactory {
private Map<String, Car>cars = null;
public InstanceCarFactory() {
cars = new HashMap<String, Car>();
cars.put("玛莎拉蒂", new Car("玛莎拉蒂", 1800000));
cars.put("法拉利", new Car("法拉利", 2000000));
}
public Car getCar(String brand) {
return cars.get(brand);
}
}

beans-factory.xml:

1
2
3
4
5
6
7
8
9
10
11
<!-- 配置工厂实例 -->
<bean id="carfactory" class="com.beanfactory.InstanceCarFactory"></bean>
<!-- 通过实例方法来配置bean -->
<!--
factory-bean:指向实例方法bean
factory-method:指向工厂方法名
constructor-arg:如果工厂方法需要参数,则使用constructor-arg来配置参数
-->
<bean id="car2" factory-bean="carfactory" factory-method="getCar">
<constructor-arg value="法拉利"></constructor-arg>
</bean>

通过FactoryBean配置Bean

Spring 中有两种类型的 Bean, 一种是普通Bean, 另一种是工厂Bean, 即FactoryBean.
工厂 Bean 跟普通Bean不同, 其返回的对象不是指定类的一个实例, 其返回的是该工厂 Bean 的 getObject 方法所返回的对象

例:
CarFactoryBean.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.factoryBean;
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car>{
private String brand;
public void setBrand(String brand) {
this.brand = brand;
}
// 返回bean的对象
@Override
public Car getObject() throws Exception {
return new Car(brand, 1500000);
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return true;
}
}

注意:一开始我没有声明brand更没有setBrand方法,结果报异常了

beans-factory.xml:

1
2
3
4
5
6
7
8
9
<!--
通过FactoryBean 来配置 Bean 的实例
class: 指向FactoryBean 的全类名
property: 配置 FactoryBean 的属性
但实际返回的实例确是 FactoryBean 的 getObject() 方法返回的实例!
-->
<bean id="car3" class="com.factoryBean.CarFactoryBean">
<property name="brand" value="保时捷"></property>
</bean>

Newer Post

Spring4.0学习9--通过注解配置bean

一、在 classpath 中扫描组件 组件扫描(component scanning): Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件.特定组件包括: @Component: 基本注解, 标识了一个受 Spring 管理的组件 @Respository …

继续阅读
Older Post

Spring4.0学习7--IOC 容器中 Bean 的生命周期方法 和 创建 Bean 后置处理器

IOC 容器中 Bean 的生命周期方法 Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.Spring IOC 容器对 Bean 的生命周期进行管理的过程: 通过构造器或工厂方法创建 Bean 实例 为 Bean 的属性设 …

继续阅读