BeanFactory、FactoryBean和ObjectFactory、ApplicationContext的入门理解

概述

BeanFactory 和 FactoryBean 从字面意思可以知道:Bean工厂、工厂Bean

ObjectFactory

BeanFactory

以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂

在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

负责配置、创建、管理Bean

BeanFactory 本身只是一个接口

BeanFactory作为bean工厂,是spring的基础容器,它可以管理单例bean对象从创建到销毁的整个生命周期。

源码

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);

    boolean containsBean(String var1);

    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String var1) throws NoSuch BeanDefinitionException;

    @Nullable
    Class<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;

    String[] getAliases(String var1);
}

初始化顺序

  1. 创建配置文件
  2. 装载配置文件
  3. 启动 IoC 容器
  4. 获取 Bean 实例(getBean())

通过 BeanFactory 启动 IoC 容器时,并不会初始化配置文件当中定义的 Bean,初始化的动作发生在第一次调用某个 Bean 的时候

FactoryBean

以Bean结尾,表示它是一个Bean

不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取

它就是一个 Bean,而不是一个工厂

FactoryBea可以作为BeanFactory管理的bean对象,同时BeanFactory对FactoryBean会做出特殊处理。如果FactoryBean被定义为spring的bean,则获取该bean时需要在beanName前面加上&符号,否则获取的bean是FactoryBean创建的对象。

源码

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}
  1. getObject用来返回实例化后的对象
  2. getObjectType用来返回对象的类型
  3. isSingleton用来标识对象是否为单例的,这里默认为true,Spring会将实例化后的对象放入BeanFactory容器中
  4. BeanFactory中获取的并不是这个类本身,而是FactoryBean的getBean()返回的对象,如果要获取FactoryBean对象,请在id前面加一个&符号来获取:通过转义符&来区分获取FactoryBean产生的对象和FactoryBean对象本身(FactoryBean实现类)

ObjectFactory

只是作为一个普通的对象工厂,也不作为spring管理的bean使用,BeanFactory不会对ObjectFactory做特殊处理。它主要是用作BeanFactory子类的内部类或者使用lambda表达式封装bean的创建过程。

spring对ObjectFactory的应用之一:将创建对象的步骤封装到ObjectFactory中 交给自定义的Scope来选择是否需要创建对象来灵活的实现scope

源码

@FunctionalInterface
public interface ObjectFactory<T> {
    T getObject() throws BeansException;
}

获取单例bean及从自定义作用域中获取bean均使用 ObjectFactory调用createBean方法封装了bean的创建。

与BeanFactory区别

  1. BeanFactory实现了ObjectFactory接口
  2. ObjectFactory仅仅关注一个或者一种类型Bean的查找,并且自身不具备依赖查找的能力.
  3. BeanFactory则提供单一类型,集合类型和层次性的依赖查找能力.

参考来源

用途

这用于延迟查找的场景,当得到 ObjectFactory 对象时,相当于 Bean 没有被创建,只有当 getObject() 方法时,才会触发 Bean 实例化等生命周期
主要用于暂时性地获取某个 Bean Holder 对象,如果过早的加载,可能会引起一些意外的情况,比如当 Bean A 依赖 Bean B 时,如果过早地初始化 A,那么 B 里面的状态可能是中间状态,这时候使用 A 容易导致一些错误

ApplicationContext

ApplicationContext由BeanFactory派生而来;BeanFactory的许多功能需要编程实现,而在ApplicationContext中则可以通过配置的方式实现
ApplicationContext因此也称之为Spring上下文

可以理解成一个包含所有bean的容器,在单例模式下当有其他地方需要使用某一个bean的时候他就取出来注入到那个地方,所有在不同地方采用@Autowired注入的同一个类型的bean都是同一个bean。

源码

import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.lang.Nullable;

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    @Nullable
    String getId();

    String getApplicationName();

    String getDisplayName();

    long getStartupDate();

    @Nullable
    ApplicationContext getParent();

    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

ApplicationContext.getBean

在@Configuration类中注入ApplicationContext后使用ApplicationContext.getBean(XXX.class)获取到的bean和@Autowired注入的XXX bean都是同一个。因为他们都是来自于同一个容器。

通过ApplicationContext的getBean方法来获取Spring容器中已初始化的bean。getBean一共有以下四种方法原型:参考博客

  1. getBean(String name):参数name表示IOC容器中已经实例化的bean的id或者name,且无论是id还是name都要求在IOC容器中是唯一的不能重名。那么这种方法就是通过id或name去查找获取bean
  2. getBean(Class< T > type):参数Class<T> type表示要加载的Bean的类型。如果该类型没有继承任何父类(Object类除外)和实现接口的话,那么要求该类型的bean在IOC容器中也必须是唯一的getBean(String name)获得的对象需要类型转换而getBean(Class type)获得的对象无需类型转换。
  3. getBean(String name, Class type):适合当类型不唯一时,再通过id或者name来获取bean
  4. getBean(String name, Object[] args):本质还是通过bean的id或者name来获取bean,通过第二个参数Object[] args可以给bean的属性赋值,赋值的方式有两种:构造方法和工厂方法。但是通过这种方式获取的bean必须把scope属性设置为prototype,也就是非单例模式。

与BeanFactory区别

  1. ApplicationContext是BeanFactory的子类,并扩展了功能:BeanFactory是Spring中比较原始的Factory,它不支持AOP、Web等Spring插件,而ApplicationContext不仅包含了BeanFactory的所有功能,还支持Spring的各种插件,还以一种面向框架的方式工作以及对上下文进行分层和实现继承。
  2. 初始化:BeanFactory在初始化容器时,并未实例化 BeanApplicationContext在初始化应用上下文时,会实例化所有单实例的 Bean,所以相对来说,占用空间较大、初始化时间会比 BeanFactory 稍长
  3. 延迟加载:BeanFactroy只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化ApplicationContext在自身初始化的时候,就会一次性创建了所有的Bean
  4. 手动、自动注册:BeanFactory需要手动注册,而ApplicationContext则是自动注册

ApplicationContext扩展了很多其他功能:

  1. AOP
  2. 国际化
  3. 资源管理
  4. 事件
  5. 注解
  6. 等等
  7. 我们开发直接用的肯定是 ApplicationContext 而不是 BeanFactory

结论

BeanFactory就是对象工厂,用于实例化和保存对象。

FactoryBean是一个工厂对象,用于实例化创建过程比较复杂的对象。

ObjectFactory是某个特定的工厂,用于在项目启动时,延迟实例化对象,解决循环依赖问题。

BeanFactory和ObjectFactory:

  1. BeanFactory和ObjectFactory都提供依赖查找的能力
  2. BeanFactory实现了ObjectFactory接口
  3. ObjectFactory仅仅关注一个或者一种类型Bean的查找,并且自身不具备依赖查找的能力.
  4. BeanFactory则提供单一类型,集合类型和层次性的依赖查找能力.

BeanFactory和FactoryBean:FactoryBean的着重于自定义创建对象过程,由BeanFactory通过FactoryBean来获取目标对象,而如果是isSingleton返回true的话,spring会利用单例缓存来缓存通过FactoryBean创建的对象

ObjectFactory和FactoryBean

  1. 在将给依赖注入列表注册一个ObjectFactory类型的对象,在注入过程中会调用objectFactory.getObject()来创建目标对象注入进去
  2. 是一个普通的工厂对象接口,对于spring在doGetBean处的使用时,在于创建对象的过程由框架通过ObjectFactory定义,而创建的时机交给拓展接口Scope
  3. 通过FactoryBean你可以控制对象如何创建,而ObjectFactory借助Scope接口自定义scope你可以控制对象的创建时机

参考来源

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

?abc!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值