spring中的FactoryBean

spring中的FactoryBean

FactoryBean是一个bean!!!
FactoryBean是一个bean!!!
FactoryBean是一个bean!!!
只是它在spring中是一种特殊的bean,能够创造bean的bean.
可以理解为它是一个孕妇,孕妇是人,婴儿也是一个人~

接口

public interface FactoryBean<T> {
    
    // 返回实际产生的bean
	@Nullable
	T getObject() throws Exception;
    
    // 返回对象的类型
	@Nullable
	Class<?> getObjectType();
    
    // 是否单例
	default boolean isSingleton() {
		return true;
	}

}

示例

FactoryBean返回的类

public class Dog {

	public Dog(String name, Integer age) {
		this.name = name;
		this.age = age;
	}

	private String name;

	private Integer age;
	
    // getting and setting igr
}

DogFactoryBean

@Component
public class DogFactoryBean implements FactoryBean<Dog> {

	@Override
	public Dog getObject() throws Exception {
		return new Dog("luck",2);
		}

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

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

Main

public class Main {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext();
		configApplicationContext.register(AppConfig.class);
		configApplicationContext.refresh();
		Dog dog1 = configApplicationContext.getBean(Dog.class);
		System.out.println("dog :"+dog1);
		Dog dog2 = configApplicationContext.getBean(Dog.class);
		System.out.println("dog :"+dog2);
		DogFactoryBean bean1 = configApplicationContext.getBean(DogFactoryBean.class);
		System.out.println(bean1.getObjectType().getName());
	}
}

print :
dog :factorybean.Dog@7e5afaa6
dog :factorybean.Dog@7e5afaa6
factorybean.Dog

通过debug上面的示例得知

  1. 在spring容器中获取到Dog类型,也可以获得DogFactoryBean对象
  2. 在singleObjects中只保存了DogFactoryBean对象,并且以&开头(&dogFactoryBean)存储到BDMap中
  3. 通过2可以说明,Dog实例实在getBean的时候调用getObject()获取到的.
  4. dog对象第一遍获取是通过getObject()方法获取并加入factoryBeanObjectCache缓存中,第二遍会走factoryBeanObjectCache缓存.

spring实例化Bean的时机

1.FactoryBean实例化时机

![finishBeanFactoryInitialization(beanFactory);](_v_images/20200408115050050_9778.png =438x)

FactoryBean本身是经历了spring实例化bean的所有流程.

2. FactoryBean返回实例的实例化时机

本例中Dog在未调用getBean方法时,是没有存储在spring容器中的

获取方式 : getBean()
![Snipaste_2020-04-08_12-01-16](_v_images/20200408120143608_17259.png =438x)

在getBean时,先会从注册的FactoryBean中获取bean,所以Dog是没有经历实例化流程的.
Dog的实例化不经历spring 注册BeanDefinition的过程

FactoryBean和BeanFactory区别?

FactoryBean是一个特殊的bean,BeanFactory是一个bean的工厂

应用场景

  1. mybatis SQLSessionFactoryBean
  2. 根据某些条件返回对象交给spring的场景
  3. 返回对象属性较复杂,暴露简单配置给spring管理

spring中的FactoryBean
https://www.blaaair.com/archives/spring-zhong-de-factorybean
作者
Glo6f
发布于
2022年12月10日
许可协议