其实实例化一个Bean并没有那么复杂,不就是将new Bean()的过程放到Spring这里来实现了吗?
其实的确如此,当然了,之前的设计模式中的实例化Bean的方式Spring也得支持支持吧。
一、最直观实例化(反射模式)
xml配置
<bean id="car1" class="com.*.Car">
<property name="id" value="1"></property>
</bean>
说明:这里要把类com.*.Car实例化为一个名叫car1的对象,参数都在下面,请Spring先生实例化一下吧。
二、工厂方法模式
工厂方式与设计模式对应,分为静态工厂与动态工厂。静态工厂指的是,需要工厂进行实例化的类是固定写在代码中,不需要在配置中显式实例化。
1、静态工厂—— Factory模式
bean类Car
package com.home.factoryMethod;
public class Car {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Car [id=" + id + " ]";
}
public Car(){
}
public Car(int id, String name, int price) {
super();
this.id = id;
}
}
工厂类CarStaticFactory
package com.home.factoryMethod;
import java.util.HashMap;
import java.util.Map;
public class CarStaticFactory {
private static Map<Integer, Car> map = new HashMap<Integer,Car>();
static{
map.put(1, new Car(1);
map.put(2, new Car(2);
map.put(3, new Car(3);
}
public static Car getCar(int id){
return map.get(id);
}
}
xml配置
<bean id="Car3"
class="com.home.factoryMethod.CarStaticFactory"
factory-method="getCar">
<constructor-arg value="3"></constructor-arg>
</bean>
<bean id="Car2"
class="com.home.factoryMethod.CarStaticFactory"
factory-method="getCar">
<constructor-arg value="2"></constructor-arg>
</bean>
代码调用
public static void h(){
ApplicationContext ctx =
new ClassPathXmlApplicationContext("bean-factoryMethod.xml");
Car car2 = (Car) ctx.getBean("Car2");
System.out.println(car2 );
Car car1 = (Car) ctx.getBean("Car1");
System.out.println(car1);
}
静态工厂方法方式是非常适用于作为1个bean容器(集合的), 只不过bean集合定义在工厂类里面而不是bean config file里面。
缺点也比较明显, 把数据写在class里面而不是配置文件中违反了spring的初衷。
当然优点就是bean config file更加简洁啦。
2、动态工厂——Factory bean模式
就是将需要实例化的bean也设置在配置文件中,更加灵活。这种方式是更为常用的工厂模式。
1、实例工厂类
package com.home.factoryMethod;
import java.util.HashMap;
import java.util.Map;
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);
}
}
2、xml写法
<bean id="carFactory"
class="com.home.factoryMethod.CarInstanceFactory">
<property name="map">
<map>
<entry key="4">
<bean class="com.home.factoryMethod.Car">
<property name="id" value="4"></property>
</bean>
</entry>
<entry key="6">
<bean class="com.home.factoryMethod.Car">
<property name="id" value="6"></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>
3、客户端调用
public static void h2(){
ApplicationContext ctx =
new ClassPathXmlApplicationContext("bean-factoryMethod.xml");
Car car1 = (Car) ctx.getBean("car4");
System.out.println(car1);
car1 = (Car) ctx.getBean("car6");
System.out.println(car1);
}