Spring 的工厂方法
IoC 是典型的工厂模式。
工厂模式 就是将类创建好后,直接提供给调用者。
Spring 中 IoC 通过工厂模式创建 bean 的方式分为两种:
- 静态工厂方法
- 实例工厂方法
静态工厂
静态工厂指的是:我不需要实例化工厂类,我只需要使用工厂的静态方法即可完成实例的获取。
一个用原生 Java 实现的 静态工厂 例子。所谓静态工厂,就是 Map 集合、工厂方法 为 static。
package com.thesunandsnow.factory;
import com.thesunandsnow.entity.Car;
import java.util.HashMap;
import java.util.Map;
public class StaticCarFactory {
private static Map<Long, Car> carMap;
static {
carMap = new HashMap<Long, Car>();
carMap.put( 0L, new Car(0L, "宝马") );
carMap.put( 1L, new Car(1L, "奔驰") );
}
public static Car getCar(long id) {
return carMap.get(id);
}
}
IoC 的静态工厂
将 静态工厂交给 IoC 来管理。注意 bean 标签的 class 值即为 静态工程类在包中的路径。
<!--配置静态工厂创建 Car-->
<bean id="car" class="com.thesunandsnow.factory.StaticCarFactory" factory-method="getCar">
<constructor-arg value="2"></constructor-arg>
</bean>
其中 constructor-arg
标签值为 factory-method
的 getCar 方法的参数,等同于调用 getCar 方法 得到返回的 对象。
bean 标签的 class 属性为 工厂类,而不是实体类
因为默认是单例模式,所以在加载 xml 文件时,静态工厂就会将所有对象创建好。
在 Java 代码中直接 getBean 参数值为 静态工程bean 标签的 id ,即可取得静态工程中的对象。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-factory.xml");
Car car1 = (Car) applicationContext.getBean("car");
IoC 的实例工厂
所谓实例工厂,Map 集合、工厂方法 当然不是 static,而为 实例集合、实例方法。
package com.thesunandsnow.factory;
import com.thesunandsnow.entity.Car;
import java.util.HashMap;
import java.util.Map;
public class InstanceCarFactory {
private Map<Long, Car> carMap;
public InstanceCarFactory() {
carMap = new HashMap<Long, Car>();
carMap.put(1L, new Car(3, "大众"));
carMap.put(2L, new Car(4, "比亚迪"));
}
public Car getCar(Long id) {
return carMap.get(id);
}
}
xml 中的配置。注意 factory-bean
属性值为 工厂实例的 bean 标签 id。
<!--配置实例工厂 bean-->
<bean id="carFactory" class="com.thesunandsnow.factory.InstanceCarFactory"></bean>
<!--配置实例工厂创建 Car-->
<bean id="car2" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="1"></constructor-arg>
</bean>
业务代码中获得实例:
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("spring-factory.xml");
Car car2 = (Car) applicationContext.getBean("car2");
Spring 中 静态 与 实例工厂的区别
静态工厂在 xml 中只需要配置一个 bean ,因为工厂不需要被实例化,只需要实例化目标的 类对象。
而实例通常需要配置两个 bean 。因为 工厂 本身就需要被实例化,目标的类对象也需要被实例化。