BeanFactory和FactoryBean的区别

274 阅读1分钟

BeanFactory和FactoryBean在spring中都被定义为接口

1.BeanFactory接口

容器的抽象,定义了管理和获取bean对象的方法,如下图所示

image

2.FactoryBean

官方文档
类似一个Bean生成工具,方法定义如下

public interface FactoryBean<T> {
	@Nullable
	T getObject() throws Exception;
	@Nullable
	Class<?> getObjectType();
	default boolean isSingleton() {
		return true;
	}
}

实现了FactoryBean的类,spring会调用其getObject、getObjectType创建bean,可以在getObject方法自定义Bean的创建过程

如果想自定义bean的创建过程,并在创建完成后将bean交还由spring管理,则可实现FactoryBean接口

如mybatis-spring就是在getObject方法里对dao接口进行动态代理对象的创建,交由spring管理时将bean对应的BeanDefinition信息中的beanClass改为实现了FactoryBean的class。

public class MapperFactoryBean<T> implements FactoryBean<T> {
	private Class<T> t;
	private SqlSession sqlSession;
	
	// 其它代码省略
	public MapperFactoryBean(Class<T> t) {
		this.t = t;
	}

	@Override
	public T getObject() throws Exception {
		// 创建代理对象
		return MapperProxyUtil.getProxy(t, sqlSession);
	}

	@Override
	public Class<?> getObjectType() {
		return t;
	}
}
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {

	public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
		super(registry, false);
	}

	@Override
	public Set<BeanDefinitionHolder> doScan(String... basePackages) {
		// 获取指定包下的 BeanDefinition
		Set<BeanDefinitionHolder> hodlers = super.doScan(basePackages);
		GenericBeanDefinition definition;
        for (BeanDefinitionHolder holder : hodlers) {
            definition = (GenericBeanDefinition) holder.getBeanDefinition();
            String beanClassName = definition.getBeanClassName();

            // 修改bean class为MapperFactoryBean,并将原bean作为构造参数传入
            definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName); // 构造函数参数
            definition.setBeanClass(MapperFactoryBean.class);                                  // factory bean
            definition.getPropertyValues().add("proxyTargetName", beanClassName); // 属性注入

            // 根据类型自动注入 - 对MapperFactoryBean的一些属性的set方法进行自动调用,以注入spring容器存在的引用
            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
		return hodlers;
	}
}