官方定义

  • BeanFactory:Spring Bean容器的根接口
  • FactoryBean:各个对象的工厂接口,如果bean实现了这个接口,它将被用作对象的工厂,而不是直接作为bean实例。

源码解析

BeanFactory

public interface BeanFactory {
//标注是获取FactoryBean的实现类,而不是调用getObject()获取的实例
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}

从源码的方法定义上,就可以看出,BeanFactory作为bean的容器管理器,提供了一系列获取bean以及获取bean属性的方法。

写一个小例子试验下:

SimpleBean:

public class SimpleBean {
public void send() {
System.out.println("Hello Spring Bean!");
}
}

Spring配置文件config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="simpleBean" class="base.SimpleBeanFactoryBean"/>
</beans>

测试方法:

    public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
BeanFactory beanFactory = context.getAutowireCapableBeanFactory();
System.out.println("通过名称获取bean");
SimpleBean simpleBean = (SimpleBean) beanFactory.getBean("simpleBean");
simpleBean.send();
System.out.println("通过名称和类型获取bean");
simpleBean = beanFactory.getBean("simpleBean", SimpleBean.class);
simpleBean.send();
System.out.println("通过类型获取bean");
simpleBean = beanFactory.getBean(SimpleBean.class);
simpleBean.send();
boolean containsBean = beanFactory.containsBean("simpleBean");
System.out.println("是否包含 simpleBean ? " + containsBean);
boolean singleton = beanFactory.isSingleton("simpleBean");
System.out.println("是否是单例? " + singleton);
boolean match = beanFactory.isTypeMatch("simpleBean", ResolvableType.forClass(SimpleBean.class));
System.out.println("是否是SimpleBean类型 ? " + match);
match = beanFactory.isTypeMatch("simpleBean", SimpleBean.class);
System.out.println("是否是SimpleBean类型 ? " + match);
Class<?> aClass = beanFactory.getType("simpleBean");
System.out.println("simpleBean 的类型是 " + aClass.getName());
String[] aliases = beanFactory.getAliases("simpleBean");
System.out.println("simpleBean 的别名 : " + Arrays.toString(aliases));
}

控制台结果:

通过名称获取bean
Hello Spring Bean!
通过名称和类型获取bean
Hello Spring Bean!
通过类型获取bean
Hello Spring Bean!
是否包含 simpleBean ? true
是否是单例? true
是否是SimpleBean类型 ? true
是否是SimpleBean类型 ? true
simpleBean 的类型是 base.SimpleBean
simpleBean 的别名 : []

FactoryBean

public interface FactoryBean<T> {

    /**
* 获取一个bean,如果配置了工厂bean,在getBean的时候,将会调用此方法,获取一个bean
*/
T getObject() throws Exception; /**
* 获取bean的类型
*/
Class<?> getObjectType(); /**
* 是否是单例
*/
boolean isSingleton(); }

接口是泛型,定义了三个方法,其中getObject()是工厂模式的体现,将会通过此方法返回一个bean的实例。

一个小例子:

public class SimpleBeanFactoryBean implements FactoryBean<SimpleBean> {
@Override
public SimpleBean getObject() throws Exception {
System.out.println("MyFactoryBean getObject");
return new SimpleBean();
} @Override
public Class<?> getObjectType() {
System.out.println("MyFactoryBean getObjectType");
return SimpleBean.class;
} @Override
public boolean isSingleton() {
return false;
}
}

以上可以修改为单例模式,可以做成线程安全的单例,可塑性较高。

配置文件config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="simple" class="base.SimpleBeanFactoryBean"/>
</beans>

注意,我们在这里只配置了SimpleBeanFactoryBean,并没有配置SimpleBean,接下来看下getBean方法的输出。

ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
SimpleBean simpleBean = context.getBean(SimpleBean.class);
simpleBean.send();

控制台输出:

MyFactoryBean getObjectType
MyFactoryBean getObject
Hello Spring Bean!

由此我们可以看出FactoryBean的执行流程

  1. 通过getObjectType获取bean的类型
  2. 调用getObject方法获取bean的实例

总结

BeanFactoryFactoryBean其实没有关系,只是名称比较像而已。

  • BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范。
  • FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

Spring的BeanFactory和FactoryBean的更多相关文章

  1. Spring中BeanFactory与FactoryBean的区别

    在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层 ...

  2. 【Java面试】Spring中 BeanFactory和FactoryBean的区别

    一个工作了六年多的粉丝,胸有成竹的去京东面试. 然后被Spring里面的一个问题卡住,唉,我和他说,6年啦,Spring都没搞明白? 那怎么去让面试官给你通过呢? 这个问题是: Spring中Bean ...

  3. Spring中BeanFactory与FactoryBean到底有什么区别?

    一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean().containsBean()等管理Bea ...

  4. Spring之BeanFactory和FactoryBean接口的区别

    目录 一.BeanFactory接口 二.FactoryBean接口 1.简单实现 2.增强实现 3.FactoryBean的实际使用案例 三.总结 @   Spring框架中的BeanFactory ...

  5. spring中BeanFactory和FactoryBean的区别

    共同点: 都是接口 区别: BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂 在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器 ...

  6. BeanFactory 和FactoryBean的区别

    转自:https://www.cnblogs.com/aspirant/p/9082858.html BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是 ...

  7. Difference between BeanFactory and FactoryBean in Spring Framework (Spring BeanFactory与Factory区别)

    参见原文:http://www.geekabyte.io/2014/11/difference-between-beanfactory-and.html geekAbyte Codes and Ran ...

  8. Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

    Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...

  9. Spring BeanFactory 与 FactoryBean 的区别

    BeanFactory 和 FactoryBean 都是Spring Beans模块下的接口 BeanFactory是spring简单工厂模式的接口类,spring IOC特性核心类,提供从工厂类中获 ...

随机推荐

  1. python学习Day7--字符串操作

    [主要内容] 1. 补充基础数据类型的相关知识点 1. str. join() 把列表变成字符串 2. 列表不能再循环的时候删除. 因为索引会跟着改变 3. 字典也不能直接循环删除. 把要删除的内容记 ...

  2. 非常NB的一款快捷启动软件--Merry

    Merry 被设计为了能将日常重复性操作简化为一个快捷键或者命令.Merry 采用完全开放的体系, 可以使用 Lua 或者外部程序来扩展 Merry 的功能. 另附一个自己扩展的LUA脚本: --启动 ...

  3. 在4K屏下以超过VMWare默认的最高分辨率运行Linux系统

    前言 4K 屏,有其优点也有其弊端.优点就是分辨率高,字体和图标看起来如丝一般顺滑:缺点就是字体和图标小,费眼睛.解决这个缺点的方法也很简单粗暴,就是将系统的显示比例放大.在高分屏不很普及的时候,无论 ...

  4. 使用PyCharm创建并运行一个Python项目

    (1)首先,在欢迎界面点击“Create New Project”: (2)在“New Project“左侧面板点击”Pure Python“,右侧Location选择自己要创建项目的路径(一般情况, ...

  5. 形象解释各种卷积算法(Convolution animations)

    No padding, no strides Arbitrary padding, no strides Half padding, no strides Full padding, no strid ...

  6. UVA1623 Enter The Dragon (贪心)

    题意: m个坑,n天,起初每个坑都是满的,每天至多有一个坑会下雨,下雨就会满,满了再下就输出no. 在没有雨的时候可以安排龙来喝水,把坑喝空,可行的话输出龙喝水的方案 思路: 边读入边操作,set保存 ...

  7. HTML5与HTML4的区别-----通用的排版结构

    一个网页通常分为:头部,主体内容和脚部三个部分,当然也有其他更细的划分方法. 以移动端为例, 当给一个设计图,我通常使用一下结构: <div  class="container&quo ...

  8. TCP、UDP 协议的区别

    TCP 面向连接 可靠 传输形式:字节流 传输效率:慢 所需资源:多 首部字节:20-60 应用场景:要求通讯数据可靠(如文件传输.邮件传输) UPD 无连接 不可靠 传输形式:数据报文段 传输效率: ...

  9. VFP 的 SPT 起跳 -- 陈纯(BOE数据网络工作室)

    细节描述 Visual FoxPro 的 SPT 技术快速入门 说在前面熟悉 Fox 的朋友都知道,在 VFP 里我们可以使用远程视图 (Remote View) 和 SPT(SQL Pass Thr ...

  10. Hexo搭建静态博客踩坑日记(二)

    前言 Hexo搭建静态博客踩坑日记(一), 我们说到利用Hexo快速搭建静态博客. 这节我们就来说一下主题的问题与主题的基本修改操作. 起步 chrome github hexo git node.j ...