ApplicationContext 和beanFactory 和 factoryBean的区别以及联系
时间:2022-07-23
本文章向大家介绍ApplicationContext 和beanFactory 和 factoryBean的区别以及联系,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
背景
最近有看一些面试题,很多框架都有提到三者的关系和区别。所以今天打算看一下。
简单描述
beafactory是Spring IOC中的基础容器,用来解析BeanDefination存放bean的容器,还会对外提供一些操作bean的接口,AplicationContext是BeanFactory的扩展容器,基于BeanFactory 将其和其他组件整合到了一起。而factoryBean是以bean结尾的我们就可以知道它是以bean结尾的,所以我们可以认为他是一个特殊的bean,可以用来生产bean的一个bean,有点绕口。
beanFactory
- BeanFactory是IOC容器的顶层方法,他也可以说是SpringIOC容器之一吧(另一个就是他的扩展容器ApplicationContext)。
- 先看BeanFactory的源码,我们可以看到他的这些基础接口方法都是一些获取和判断bean的一些属性的方法。
public interface BeanFactory {
//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = "&";
//根据bean的名字,获取在IOC容器中得到bean实例
Object getBean(String name) throws BeansException;
//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
<T> T getBean(String name, @Nullable 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;
//提供对bean的检索,看看是否在IOC容器有这个名字的bean
boolean containsBean(String name);
//根据bean名字得到bean实例,并同时判断这个bean是不是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
//得到bean实例的Class类型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
String[] getAliases(String name);
}
- BeanFactory只是一个对外暴露的接口,而具体的实现有很多种 如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。 都是附加了某种功能的实现。 它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。 也可以这么说吧,BeanFactory就是Spring的基础容器对外暴露的接口。
- 我们再来看看实现这个接口的类都有哪些
FactoryBean
- 看看源码和使用。
package org.springframework.beans.factory;
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
/**
* @authoryuanxindong
* @date: 2020/6/9 8:43 下午
*/
public class FactoryBeanStudy implements FactoryBean<Person> {
private String personInfo;
@Override
public Person getObject() throws Exception {
Person person = new Person();
String[] split = personInfo.split(",");
String s = split[1];
person.setName(s);
return person ;
}
@Override
public Class<?> getObjectType() {
return Person.class;
}
@Override
public boolean isSingleton() {
return false;
}
public void setPersonInfo(String personInfo) {
this.personInfo = personInfo;
}
}
- 其实我一直不能理解这个FactoryBean到底是想干什么的,于是大概想了一下。且最终结果是现在大家都在使用SpringBoot还有Spring的注解。已经真的很难感受到之前xml注册bean的繁琐了。所以真的是深切的体会不到FactoryBean使用的便捷。虽然FactoryBean在框架里面有被实现和使用70多种但是在平时的开发也不会遇到这些东西,所以真的是感觉到尤为陌生。
- 一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean。在某些情况下,实例化bean过程复杂,则就需要我们书写xml文件,在中书写大量的配置信息,配置的方式的灵活性是受限的,这个时候采用编码的方式会得到一个相对简单的解决方案,那就是通过FactoryBean来创建这个bean(FactoryBean也是一个Bean,他的特殊之处是可以生产bean.把她想成一个女人,bean是人类)其实也可以想成工厂方法的装饰器模式。
- 还有就是FactoryBean在AOP中的使用,我们知道AOP实际上是Spring在运行时创建了一个代理对象,也就是说这个对象,是我们在运行时创建的,而不是一开始就定义好的,这很符合工厂方法模式。更形象地说,AOP代理对象通过Java的反射机制,在运行时创建了一个代理对象,在代理对象的目标方法中根据业务要求织入了相应的方法。这个对象在Spring中就是——ProxyFactoryBean。 所以,FactoryBean为我们实例化Bean提供了一个更为灵活的方式,我们可以通过FactoryBean创建出更为复杂的Bean实例。
ApplicationContext
还有结合上面的依赖图可知:
- 如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的躯体了,ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置实现。
- BeanFactorty接口提供了配置框架及基本功能,但是无法支持spring的aop功能和web应用。而ApplicationContext接口作为BeanFactory的派生,因而提供BeanFactory所有的功能。而且ApplicationContext还在功能上做了扩展,相较于BeanFactorty,ApplicationContext还提供了以下的功能:
- MessageSource, 提供国际化的消息访问
- 资源访问,如URL和文件
- 事件传播特性,即支持aop特性
- 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
- ApplicationContext:是IOC容器另一个重要接口, 它继承了BeanFactory的基本功能, 同时也继承了容器的高级功能,如:MessageSource(国际化资源接口)、ResourceLoader(资源加载接口)、ApplicationEventPublisher(应用事件发布接口)等。
总结
ApplicationContext(扩展的Bean容器对外接口) 和 factoryBean(就是一个特殊的Bean) 都依赖 beanFactory(基础容器对外接口)
参考文章
https://www.cnblogs.com/xiaoxi/p/5846416.html https://www.cnblogs.com/aspirant/p/9082858.html
- Codevs2018 反病毒软件
- 2953: [Poi2002]商务旅行
- 1230: [Usaco2008 Nov]lites 开关灯
- 【推荐】C#线程篇---你所不知道的线程池(4)
- 洛谷P1333 瑞瑞的木棍(欧拉回路)
- 【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.1)
- 【LeetCode 20】关关的刷题日记45 – Valid Parenthese
- 1819: [JSOI]Word Query电子字典
- 【推荐】C#线程篇---Task(任务)和线程池不得不说的秘密(5.2)
- javascript 事件基础
- 算法模板——sap网络最大流 3(递归+邻接矩阵)
- 从Hash Killer I、II、III论字符串哈希
- angularjs 缓存详解
- 算法模板——线段树7(骰子翻转问题)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 一个简单的图片爬虫,Python图片采集下载
- 百度统计后台总是被广告骚扰?看看应用python是如何实现的
- Python电商爬虫,法国亚马逊商品采集
- Python堆糖网图片爬虫,多进程及多线程的使用例子
- Python Post提交简单案例,文本内容在线语音合成
- Python多线程爬虫,主播信息资料爬取采集
- 基于Tensorflow2 Lite在Android手机上实现图像分类
- Python知乎专栏爬虫,pdfkit专栏文章制作PDF电子书
- Python爬虫练手,一个简单的Python资讯采集案例
- Python与seo,百度关键词相关搜索关键词采集源码
- istio请求路由分析
- [剑指]2空格替换
- (补充)SPAN+AVISPA for Verifying Cryptographic Protocols
- 如何修改终端中$符号前面的一串名称?
- Alfred 有多强悍,我写了个一键上传图片的 workflow 来告诉你