我们通常会采用xml或者注解来配置bean,在前者又分为三类
反射模式
1 | <bean id="car1" class="io.github.cc.factoryMethod.Car"> |
其中反射模式最常见,需要在bean 配置中指明bean object的全类名,Spring利用Java反射机制创建这个bean
工厂方法模式
在工厂方法模式中, Spring不会直接利用反射机制创建bean对象, 而是会利用反射机制先找到Factory类,然后利用Factory再去生成bean对象
而Factory Mothod方式也分两种,分别是静态工厂方法和实例工厂方法
静态工厂方法
1 | public class Car { |
1 | <bean id="bmwCar" class="me.changjie.domain.CarStaticFactory" factory-method="getCar"> |
可以见到,利用静态工厂方法定义bean中class属性不在是bean的全类名, 而是静态工厂的全类名, 而且还需要指定工厂里的 getBean 静态方法名字和参数
实例工厂方法
所谓实例工厂方式就是里面的getCar 方法不是静态的, 也就是代表要先实例1个工厂对象, 才能依靠这个工厂对象去获得bean 对象1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class CarInstanceFactory {
private Map<Integer, Car> map = new HashMap<Integer,Car>();
public void setMap(Map<Integer, Car> map) {
this.map = map;
}
public CarInstanceFactory(){
}
//此处非静态方法,所以工厂需要实例化
public Car getCar(int id){
return map.get(id);
}
}
1 | <bean id="carFactory" class="io.github.cc.factoryMethod.CarInstanceFactory"> |
因为实例工厂本身要实例化, 所以我们可以在xml中 指定它里面容器的data
Factory Bean模式
FactoryBean 用法可以与Factory Method有点类似,我们同样需要写1个工厂类,只不过spring提供了1个叫做FactoryBean的接口
我们的工厂类必须实现这个接口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
27
28
29
30
31public class CarBeanFactory implements FactoryBean<Car>{
private int id;
private String brand;
public void setId(int id) {
this.id = id;
}
public void setBrand(String brand) {
this.brand = brand;
}
//利用工厂类生产的bean对象, 通常在里面new 1个 对象就ok
@Override
public Car getObject() throws Exception {
return new Car(id, brand, 0);
}
//指明bean的对象的class
@Override
public Class<?> getObjectType() {
return Car.class;
}
//bean是否单例
@Override
public boolean isSingleton() {
return true;
}
}
1 | <bean id="esCar" class="me.changjie.domain.CarFactoryBean"> |