BeanFactory和FactoryBean的区别

这是我参与更文挑战的第3天,活动详情查看: 更文挑战

这是一道很常见的spring面试题,要说两者相似的地方,就是他们都可以用来创建spring管理的bean对象。
但是别看他们名字有点像,但其实他们之间可以说是完全不同的两个东西,也没有任何关联。

一、BeanFactory

BeanFactory,看名字我们可以知道他是一个工厂类,他是springbean容器的根接口,在spring中,所有的bean对象都是由BeanFactory来生产并管理的,其实也就是我们常常提到的IOC容器。

BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等.

二、FactoryBean

我们上面说到BeanFactory和FactoryBean都可以用来创建对象,但是区别是BeanFactory创建对象需要严格遵守生命周期,整个流程既紧密又复杂。如果我们想要自定义一个自己的bean对象,并且把这个bean交给spring管理,那么久需要实现FactoryBean接口。

来先看下他的源码:

public interface FactoryBean<T> {

	/**
	 *  获取泛型T的实例,用来创建Bean
	 * 这里默认获取的是泛型T的实例,而不是FactoryBean实例
	 */
	@Nullable
	T getObject() throws Exception;

	/**
	 * 返回T的类型,如果T是一个接口,则返回具体实现类
	 */
	@Nullable
	Class<?> getObjectType();

	/**
	 * FactoryBean#getObject返回的bean实例是否是单例的
	 * 如果是单例,那么FactoryBean#getObject将只会被调用一次
	 */
	default boolean isSingleton() {
		return true;
	}

}
复制代码

我们来自己实现以下这个接口

public class Car {
}
@Component
public class MyFactoryBean implements FactoryBean<Car> {
	@Override
	public Car getObject() throws Exception {
		return new Car();
	}

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

	@Override
	public boolean isSingleton() {
		return true;
	}
}
复制代码

来打印一下这个我们自定义的bean

public class Test {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac =
			new AnnotationConfigApplicationContext(AppConfig.class);
//		AbstractAutowireCapableBeanFactory beanFactory = (AbstractAutowireCapableBeanFactory) ac.getBeanFactory();
//		beanFactory.setAllowCircularReferences(false);
//		ac.register(AppConfig.class);
//		ac.refresh();

		System.out.println(ac.getBean("myFactoryBean"));
	}
}
复制代码

输出结果:

com.bean.Car@5c1a8622

可以看到,我们并没有把car这个类交给spring管理,但是通过自定义bean实现了FactoryBean接口,FactoryBean#getObject方法获取到的就是我们的Car对象,如果isSingleton返回的是true,那么每次调用getObject方法返回的都是同一个对象。

那么我们自定义的MyFactoryBean这个bean对象又去哪里了呢?我们怎么来拿到他?

ac.getBean("&myFactoryBean")

我们只需要在beanName前面加上&符号,就能得到这个对象本身。

以上,感谢阅读。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享