Spring-Spring的多种模式配置bean

我们通常会采用xml或者注解来配置bean,在前者又分为三类

  • 反射模式
  • 工厂方法模式
    • 静态工厂方法
    • 实例工厂方法
  • FactoryBean模式

反射模式

1
2
3
4
5
<bean id="car1" class="io.github.cc.factoryMethod.Car">
<property name="id" value="1"></property>
<property name="name" value="Honda"></property>
<property name="price" value="300000"></property>
</bean>

其中反射模式最常见,需要在bean 配置中指明bean object的全类名,Spring利用Java反射机制创建这个bean

工厂方法模式

在工厂方法模式中, Spring不会直接利用反射机制创建bean对象, 而是会利用反射机制先找到Factory类,然后利用Factory再去生成bean对象
而Factory Mothod方式也分两种,分别是静态工厂方法和实例工厂方法

静态工厂方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Car {
...
}
public class CarStaticFactory {
private static Map<Integer, Car> map = new HashMap<Integer,Car>();

static{
map.put(1, new Car(1,"Honda",300000));
map.put(2, new Car(2,"Audi",440000));
map.put(3, new Car(3,"BMW",540000));
}
//静态方法获取
public static Car getCar(int id){
return map.get(id);
}
}
1
2
3
4
5
6
7
<bean id="bmwCar" class="me.changjie.domain.CarStaticFactory" factory-method="getCar">
<constructor-arg value="3"></constructor-arg>
</bean>

<bean id="audiCar" class="me.changjie.domain.CarStaticFactory" factory-method="getCar">
<constructor-arg value="2"></constructor-arg>
</bean>

可以见到,利用静态工厂方法定义bean中class属性不在是bean的全类名, 而是静态工厂的全类名, 而且还需要指定工厂里的 getBean 静态方法名字和参数

实例工厂方法

所谓实例工厂方式就是里面的getCar 方法不是静态的, 也就是代表要先实例1个工厂对象, 才能依靠这个工厂对象去获得bean 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public 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
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
<bean id="carFactory" class="io.github.cc.factoryMethod.CarInstanceFactory">
<property name="map">
<map>
<entry key="4">
<bean class="io.github.cc.factoryMethod.Car">
<property name="id" value="4"></property>
<property name="name" value="Honda"></property>
<property name="price" value="300000"></property>
</bean>
</entry>

<entry key="6">
<bean class="io.github.cc.factoryMethod.Car">
<property name="id" value="6"></property>
<property name="name" value="ford"></property>
<property name="price" value="500000"></property>
</bean>
</entry>
</map>
</property>
</bean>

<bean id="car4" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="4"></constructor-arg>
</bean>

<bean id="car6" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="6"></constructor-arg>
</bean>

因为实例工厂本身要实例化, 所以我们可以在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
31
public 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
2
3
4
<bean id="esCar" class="me.changjie.domain.CarFactoryBean">
<property name="id" value="111"></property>
<property name="brand" value="es200"></property>
</bean>
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×