两者区别

相同点:都是用来创建bean对象的
不同点:使用BeanFactory创建对象的时候,必须要遵循严格的生命周期流程,太复杂了,如果想要简单的自定义某个对象的创建,同时创建完成的对象想交给spring来管理,那么就需要实现FactroyBean接口了

BeanFactory是Spring容器的顶级接⼝,给具体的IOC容器的实现提供了规范。
FactoryBean也是接⼝,为IOC容器中Bean的实现提供了更加灵活的⽅式,FactoryBean在IOC容器的基础上给Bean的实现加上了⼀个简单⼯⼚模式和装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式,Decoration) 我们可以在getObject()⽅法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类.

区别:BeanFactory是个Factory,也就是IOC容器或对象⼯⼚,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进⾏管理的。
但对FactoryBean⽽⾔,这个Bean不是简单的Bean,⽽是⼀个能⽣产或者修饰对象⽣成的⼯⼚Bean,它的实现与设计模式中的⼯⼚模式和修饰器模式类似

BeanFactory:BeanFactory接口的类表明此类是一个工厂,是一个IOC容器,作用就是配置、新建、管理各种容器中的Bean。

FactoryBean:实现FactoryBean的类表明此类也是一个Bean,类型为工厂Bean(Spring中共有两种bean,一种为普通bean,另一种则为工厂bean)。作用是用来向容器中注册和初始化bean的。
注意:实现了FactoryBean的类例如叫CembFactoryBean,其中getObject方法是注册bean,在bean在容器中注册之后,通过id为cembFactoryBean去拿是直接拿到的getObject注册的bean,而不能拿到其本身,如果想要拿到其本身必要在id前加一个&符号。

image.png
BeanFactory是个bean 工厂类接口,是负责生产和管理bean的工厂,是IOC容器最底层和基础的接口,spring用它来管理和装配普通bean的IOC容器,它有多种实现,比如AnnotationConfigApplicationContext、XmlWebApplicationContext等。

image.png
FactoryBean是FactoryBean属于spring的一个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂bean,由spring管理,生产的对象是由getObject()方法决定的。

注意:它是泛型的,只能固定生产某一类对象,而不像BeanFactory那样可以生产多种类型的Bean。在对于某些特殊的Bean的处理中,比如Bean本身就是一个工厂,那么在其进行单独的实例化操作逻辑中,可能我们并不想走spring的那一套逻辑,此时就可以实现FactoryBean接口自己控制逻辑。


BeanFactory

BeanFactory,以Factory结尾,表示它是⼀个⼯⼚类(接⼝), 它负责⽣产和管理bean的⼀个⼯⼚。在Spring中,BeanFactory是IOC容器的核⼼接⼝,它的职责包括:**实例化、定位、配置应⽤程序中的对象及建⽴这些对象间的依赖。

BeanFactory只是个接⼝,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常⽤的⼀个,该实现将以XML⽅式描述组成应⽤的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并⽤它来构建⼀个完全可配置的系统或应⽤。
都是附加了某种功能的实现。它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。
BeanFactory和ApplicationContext就是spring框架的两个IOC容器,现在⼀般使⽤ApplicationnContext,其不但包含了BeanFactory的作⽤,同时还进⾏更多的扩展。

BeanFacotry是spring中⽐较原始的Factory。如XMLBeanFactory就是⼀种典型的BeanFactory。
原始的BeanFactory⽆法⽀持spring的许多插件,如AOP功能、Web应⽤等。ApplicationContext接⼝,
它由BeanFactory接⼝派⽣⽽来,
ApplicationContext包含BeanFactory的所有功能,通常建议⽐BeanFactory优先
ApplicationContext以⼀种更向⾯向框架的⽅式⼯作以及对上下⽂进⾏分层和实现继承,
ApplicationContext包还提供了以下的功能:

  • MessageSource, 提供国际化的消息访问
  • 资源访问,如URL和⽂件
  • 事件传播
  • 载⼊多个(有继承关系)上下⽂ ,使得每⼀个上下⽂都专注于⼀个特定的层次,⽐如应⽤的web层;

BeanFactory提供的⽅法及其简单,仅提供了六种⽅法供客户调⽤:

  • boolean containsBean(String beanName) 判断⼯⼚中是否包含给定名称的bean定义,若有则返回true
  • Object getBean(String) 返回给定名称注册的bean实例。根据bean的配置情况,如果是
  • singleton模式将返回⼀个共享实例,否则将返回⼀个新建的实例,如果没有找到指定bean,该⽅法可能会抛出异常
  • Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
  • boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
  • String[] getAliases(String name) 返回给定bean名称的所有别名

FactoryBean

⼀般情况下,Spring通过反射机制利⽤ 的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程⽐较复杂,如果按照传统的⽅式,则需要在 中提供⼤量的配置信息。配置⽅式的灵活性是受限的,这时采⽤编码的⽅式可能会得到⼀个简单的⽅案。

Spring为此提供了⼀个org.springframework.bean.factory.FactoryBean的⼯⼚类接⼝,⽤户可以通过实现该接⼝定制实例化Bean的逻辑。FactoryBean接⼝对于Spring框架来说占⽤重要的地位,Spring⾃身就提供了70多个FactoryBean的实现。它们隐藏了实例化⼀些复杂Bean的细节,给上层应⽤带来了便利。从Spring3.0开始,FactoryBean开始⽀持泛型,即接⼝声明改为 FactoryBean 的形式以Bean结尾,表示它是⼀个Bean,不同于普通Bean的是:它是实现了 FactoryBean 接⼝的Bean,根据该Bean的ID从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,⽽不是FactoryBean本身,如果要获取FactoryBean对象,请在id前⾯加⼀个&符号来获取。

例如⾃⼰实现⼀个FactoryBean,功能:⽤来代理⼀个对象,对该对象的所有⽅法做⼀个拦截,在调⽤前后都输出⼀⾏LOG,模仿ProxyFactoryBean的功能。
FactoryBean是⼀个接⼝,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,⽽是这个实现类中的getObject()⽅
法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

  1. package org.springframework.beans.factory;
  2. public interface FactoryBean<T> {
  3. T getObject() throws Exception;
  4. Class<?> getObjectType();
  5. boolean isSingleton();
  6. }

在该接⼝中还定义了以下3个⽅法:

  • TgetObject():返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中;
  • booleanisSingleton():返回由FactoryBean创建的Bean实例的作⽤域是singleton还是prototype
  • ClassgetObjectType():返回FactoryBean创建的Bean类型。

当配置⽂件中 的class属性配置的实现类是FactoryBean时,通过getBean()⽅法返回的不是
FactoryBean本身,⽽是FactoryBean#getObject()⽅法所返回的对象,相当于
FactoryBean#getObject()代理了getBean()⽅法。