打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Spring 这几道令人混淆的面试题,怎么说?
userphoto

2022.06.16 江苏

关注

继上篇 Spring 开胃菜 之后,这篇我们继续来盘盘 Spring 面试题。

这篇主要介绍几个比较容易混淆的概念,防止被问到的时候一脸懵逼。

比如 BeanFactory 、FactoryBean、ObjectFactory 的区别?等等。

话不多说,发车!

BeanFactory 什么用

BeanFactory 其实就是 IOC 的底层容器

我们都说 Spring 是 IOC 容器,说的再直白点,其实就是 Bean 的工厂,它帮我们生产和管理 Bean,如果我们需要 Bean 就从工厂拿到 bean,所以再来理解下 BeanFactory 这个名字,就知晓它就是 Spring 的核心。

例如我们调用 getBean ,这就是 BeanFactory 定义的方法,通过它得到 Bean。

不过一般我们所述的 BeanFactory 指的是它实现类,例如 DefaultListableBeanFactory。

BeanFactory 本身只是一个接口。

FactoryBean 又是啥

从命名角度来看,我们可以得知它就是一个 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")

ObjectFactory 又是啥

从命名角度来看,它是一个工厂。

好吧,摊牌了,没啥特殊含义,就是一个工厂。

在前面我写的循环依赖文章里就用到它了,三级缓存的 map 里面存储的就是 ObjectFactory,用于延迟代理对象的创建。

其实就是封装对象的创建过程,像三级缓存里的 ObjectFactory 逻辑就是判断这个 Bean 是否有代理,如果有则返回代理对象,没有则返回原来传入的对象。

ApplicationContext 呢

ApplicationContext 对我们来说应该很熟悉,我们基本上都是基于 ApplicationContext 操作的。

它也实现了 BeanFactory 这个接口,也属于一个 BeanFactory ,但是它内部还包装了一个 BeanFactory 的实现,这属于组合

而关于 Spring Beans 的一些操作都是委托内部的 BeanFactory 来操作的

所以它有 BeanFactory 的所有功能,并且基于此它还扩展了很多其他功能:

  • AOP
  • 国际化
  • 资源管理
  • 事件
  • 注解
  • 等等

因此,我们开发直接用的肯定是 ApplicationContext 而不是 BeanFactory。

Bean 一共有几种作用域

从官网,我们很容易可以得知,最新版本一共有六种作用域:

  • singleton:默认是单例,含义不用解释了吧,一个 IOC 容器内部仅此一个
  • prototype:原型,多实例
  • request:每个请求都会新建一个属于自己的 Bean 实例,这种作用域仅存在 Spring Web 应用中
  • session:一个 http session 中有一个 bean 的实例,这种作用域仅存在 Spring Web 应用中
  • application:整个 ServletContext 生命周期里,只有一个 bean,这种作用域仅存在 Spring Web 应用中
  • websocket:一个 WebSocket 生命周期内一个 bean 实例,这种作用域仅存在 Spring Web 应用中

别背网上那些多年前的答案了,以上才是最新的~

Spring 一共有几种注入方式

  • 构造器注入,Spring 倡导构造函数注入,因为构造器注入返回给客户端使用的时候一定是完整的。
  • setter 注入,可选的注入方式,好处是在有变更的情况下,可以重新注入。
  • 字段注入,就是平日我们用 @Autowired 标记字段
  • 方法注入,就是平日我们用 @Autowired 标记方法
  • 接口回调注入,就是实现 Spring 定义的一些内建接口,例如 BeanFactoryAware,会进行 BeanFactory 的注入

其实官网上关于注入就写了构造器和setter :

像字段注入其实官方是不推荐的使用的。

因为字段注入依赖注解,然后无法注入静态字段,无法控制成员变量注入顺序。

emmmm...怎么说呢,反正我字段注入用的最多,你们呢,哈哈哈。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
死磕Spring之IoC篇 - 深入了解Spring IoC(面试题)
【小家Spring】一文读懂Spring中的BeanFactory和FactoryBean(以及它和ObjectFactory的区别)的区别
SpringBean初始化过程
SpringIOC源码解析(2)—— 简单容器
Spring8:一些常用的Spring Bean扩展接口
Spring核心容器 BeanFactory和ApplicationContext 简介
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服