这是我参与更文挑战的第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前面加上&符号,就能得到这个对象本身。
以上,感谢阅读。