Spring源码笔记-2.2 FactoryBean

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package org.springframework.beans.factory;

public interface FactoryBean<T> {
  	//返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中
    T getObject() throws Exception;
	//返回FactoryBean创建的bean类型
    Class<?> getObjectType();
	//返回bean实例的作用域是singleton还是prototype
    boolean isSingleton();
}

​ 当配置文件的class属性配置的实现类是FactoryBean 时,通过getBean() 方法返回的不是FactoryBean 本身,而是FactoryBean.getObject() 方法所返回的对象.

​ 相当于FactoryBean.getObject() 代理了getBean() 方法.

​ 例如,如果使用传统方式配置Car的bean,Car的每个属性对应一个 元素标签

1
2
3
4
5
6
public class Car {
  private int maxSpeed;
  private String brand;
  private double price;
  //get/set
}

​ 如果使用FactoryBean的方式就会灵活一些,下面通过逗号分隔符的方式一次性地为Car的所有属性指定配置值:

 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 CarFactoryBean implements FactoryBean<Car> {
    private String carInfo;

    @Override
    public Car getObject() throws Exception {
        Car car = new Car();
        String[] infos = carInfo.split(",");
        car.setBrand(infos[0]);
        car.setMaxSpeed(Integer.valueOf(infos[1]));
        car.setPrice(Double.valueOf(infos[2]));
        return car;
    }

    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    public String getCarInfo() {
        return carInfo;
    }

    public void setCarInfo(String carInfo) {
        this.carInfo = carInfo;
    }
}

有了这个CarFactoryBean之后,就可以在配置文件使用下面这种自定义的配置方式配置Car bean了

1
<bean id="car" class="com.test.factoryBean.CarFactoryBean" carInfo="超级跑车,400,3000" />

调用 getBean(“car”) , Spring并不会返回CarFactoryBean 而是返回car

如果希望返回CarFactoryBean 那就 getBean("&car")


书本作者讲到FactoryBean 接口对于Spring框架很关键, Spring自身就提供了70多个实现.

它们隐藏了实例化一些复杂的bean的细节,给上层应用带来了便利.

疑问: 具体哪些地方用FactoryBean 带来了真正的便利呢?

答: