Spring的BeanFactory和FactoryBean
官方定义
- 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的执行流程
- 通过
getObjectType获取bean的类型 - 调用
getObject方法获取bean的实例
总结
BeanFactory和FactoryBean其实没有关系,只是名称比较像而已。
BeanFactory是IOC最基本的容器,负责生产和管理bean,它为其他具体的IOC容器提供了最基本的规范。FactoryBean是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。
Spring的BeanFactory和FactoryBean的更多相关文章
- Spring中BeanFactory与FactoryBean的区别
在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层 ...
- 【Java面试】Spring中 BeanFactory和FactoryBean的区别
一个工作了六年多的粉丝,胸有成竹的去京东面试. 然后被Spring里面的一个问题卡住,唉,我和他说,6年啦,Spring都没搞明白? 那怎么去让面试官给你通过呢? 这个问题是: Spring中Bean ...
- Spring中BeanFactory与FactoryBean到底有什么区别?
一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean().containsBean()等管理Bea ...
- Spring之BeanFactory和FactoryBean接口的区别
目录 一.BeanFactory接口 二.FactoryBean接口 1.简单实现 2.增强实现 3.FactoryBean的实际使用案例 三.总结 @ Spring框架中的BeanFactory ...
- spring中BeanFactory和FactoryBean的区别
共同点: 都是接口 区别: BeanFactory 以Factory结尾,表示它是一个工厂类,用于管理Bean的一个工厂 在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器 ...
- BeanFactory 和FactoryBean的区别
转自:https://www.cnblogs.com/aspirant/p/9082858.html BeanFacotry是spring中比较原始的Factory.如XMLBeanFactory就是 ...
- 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 ...
- Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法
Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法 1. BeanFactory BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于 ...
- Spring BeanFactory 与 FactoryBean 的区别
BeanFactory 和 FactoryBean 都是Spring Beans模块下的接口 BeanFactory是spring简单工厂模式的接口类,spring IOC特性核心类,提供从工厂类中获 ...
随机推荐
- python学习Day7--字符串操作
[主要内容] 1. 补充基础数据类型的相关知识点 1. str. join() 把列表变成字符串 2. 列表不能再循环的时候删除. 因为索引会跟着改变 3. 字典也不能直接循环删除. 把要删除的内容记 ...
- 非常NB的一款快捷启动软件--Merry
Merry 被设计为了能将日常重复性操作简化为一个快捷键或者命令.Merry 采用完全开放的体系, 可以使用 Lua 或者外部程序来扩展 Merry 的功能. 另附一个自己扩展的LUA脚本: --启动 ...
- 在4K屏下以超过VMWare默认的最高分辨率运行Linux系统
前言 4K 屏,有其优点也有其弊端.优点就是分辨率高,字体和图标看起来如丝一般顺滑:缺点就是字体和图标小,费眼睛.解决这个缺点的方法也很简单粗暴,就是将系统的显示比例放大.在高分屏不很普及的时候,无论 ...
- 使用PyCharm创建并运行一个Python项目
(1)首先,在欢迎界面点击“Create New Project”: (2)在“New Project“左侧面板点击”Pure Python“,右侧Location选择自己要创建项目的路径(一般情况, ...
- 形象解释各种卷积算法(Convolution animations)
No padding, no strides Arbitrary padding, no strides Half padding, no strides Full padding, no strid ...
- UVA1623 Enter The Dragon (贪心)
题意: m个坑,n天,起初每个坑都是满的,每天至多有一个坑会下雨,下雨就会满,满了再下就输出no. 在没有雨的时候可以安排龙来喝水,把坑喝空,可行的话输出龙喝水的方案 思路: 边读入边操作,set保存 ...
- HTML5与HTML4的区别-----通用的排版结构
一个网页通常分为:头部,主体内容和脚部三个部分,当然也有其他更细的划分方法. 以移动端为例, 当给一个设计图,我通常使用一下结构: <div class="container&quo ...
- TCP、UDP 协议的区别
TCP 面向连接 可靠 传输形式:字节流 传输效率:慢 所需资源:多 首部字节:20-60 应用场景:要求通讯数据可靠(如文件传输.邮件传输) UPD 无连接 不可靠 传输形式:数据报文段 传输效率: ...
- VFP 的 SPT 起跳 -- 陈纯(BOE数据网络工作室)
细节描述 Visual FoxPro 的 SPT 技术快速入门 说在前面熟悉 Fox 的朋友都知道,在 VFP 里我们可以使用远程视图 (Remote View) 和 SPT(SQL Pass Thr ...
- Hexo搭建静态博客踩坑日记(二)
前言 Hexo搭建静态博客踩坑日记(一), 我们说到利用Hexo快速搭建静态博客. 这节我们就来说一下主题的问题与主题的基本修改操作. 起步 chrome github hexo git node.j ...