继上篇 Spring 开胃菜 之后,这篇我们继续来盘盘 Spring 面试题。
这篇主要介绍几个比较容易混淆的概念,防止被问到的时候一脸懵逼。
比如 BeanFactory 、FactoryBean、ObjectFactory 的区别?等等。
话不多说,发车!
BeanFactory 其实就是 IOC 的底层容器。
我们都说 Spring 是 IOC 容器,说的再直白点,其实就是 Bean 的工厂,它帮我们生产和管理 Bean,如果我们需要 Bean 就从工厂拿到 bean,所以再来理解下 BeanFactory 这个名字,就知晓它就是 Spring 的核心。
例如我们调用 getBean ,这就是 BeanFactory 定义的方法,通过它得到 Bean。
不过一般我们所述的 BeanFactory 指的是它实现类,例如 DefaultListableBeanFactory。
BeanFactory 本身只是一个接口。
从命名角度来看,我们可以得知它就是一个 Bean,而不是一个工厂。
那为什么名字如此奇怪,它其实是一个接口,并且有以下几个方法
如果一个对象实现了这接口,那它就成为一种特殊的 Bean,注册到 IOC 容器之后,如果调用 getBean 获取得到的其实是 FactoryBean#getObject() 方法返回的结果。
为什么要这样做?
假设你依赖一个第三方的类 A,而我们又不能修改第三方的类,并且这个对象创建比较复杂,那么你就可以创建一个 bean 来封装它:
public class AFactoryBean implements FactoryBean<A> {
public A getObject() throws Exception {
A a = new A();
a.setXXX
....
...
return A
}
....省略一些实现
}
这样,我们 getBean("A") 会得到 AFactoryBean#getObject 的结果。
如果单纯只想要 AFactoryBean, 那么加个 “&” 即可,即 getBean("&A")
从命名角度来看,它是一个工厂。
好吧,摊牌了,没啥特殊含义,就是一个工厂。
在前面我写的循环依赖文章里就用到它了,三级缓存的 map 里面存储的就是 ObjectFactory,用于延迟代理对象的创建。
其实就是封装对象的创建过程,像三级缓存里的 ObjectFactory 逻辑就是判断这个 Bean 是否有代理,如果有则返回代理对象,没有则返回原来传入的对象。
ApplicationContext 对我们来说应该很熟悉,我们基本上都是基于 ApplicationContext 操作的。
它也实现了 BeanFactory 这个接口,也属于一个 BeanFactory ,但是它内部还包装了一个 BeanFactory 的实现,这属于组合。
而关于 Spring Beans 的一些操作都是委托内部的 BeanFactory 来操作的。
所以它有 BeanFactory 的所有功能,并且基于此它还扩展了很多其他功能:
因此,我们开发直接用的肯定是 ApplicationContext 而不是 BeanFactory。
从官网,我们很容易可以得知,最新版本一共有六种作用域:
别背网上那些多年前的答案了,以上才是最新的~
其实官网上关于注入就写了构造器和setter :
像字段注入其实官方是不推荐的使用的。
因为字段注入依赖注解,然后无法注入静态字段,无法控制成员变量注入顺序。
emmmm...怎么说呢,反正我字段注入用的最多,你们呢,哈哈哈。
。
联系客服