从源码角度来看BeanFactory和ApplicationContext的关系
大家好,我是小黑,这是年前的最后一篇推文,提前祝大家新年快乐~~
这次我们从源码角度来聊聊BeanFactory和ApplicationContext的关系,讲一些网上文章不曾提到的点。
官方描述
先来看一下官方文档中关于BeanFactory和ApplicationContext的描述。
The
org.springframework.beansandorg.springframework.contextpackages are the basis for Spring Framework’s IoC container. TheBeanFactoryinterface provides an advanced configuration mechanism capable of managing any type of object.ApplicationContextis a sub-interface ofBeanFactory. It adds:
Easier integration with Spring’s AOP features
Message resource handling (for use in internationalization)
Event publication
Application-layer specific contexts such as the
WebApplicationContextfor use in web applications.
从官方文档可以了解到:
BeanFactory接口提供了能够管理任何类型对象的高级配置机制。
ApplicationContext是BeanFactory的子接口,它增加了如下一些功能:
- 更容易与 Spring 的 AOP 集成
- 消息资源处理,用于国际化
- 事件发布
- 特定于应用程序层的上下文,如用于 web 应用程序的
WebApplicationContext。
源码简析
以下源码基于 Spring 5.0.13 版本。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
public interface ListableBeanFactory extends BeanFactory
从源码可以证实到,ApplicationContext继承了BeanFactory。
@Configurable
public class Main {
@Autowired
BeanFactory beanFactory;
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
Main bean = context.getBean(Main.class);
// false
System.out.println(context == bean.beanFactory);
context.close();
}
}
AnnotationConfigApplicationContext是ApplicationContext的一个实现类,换而言之,AnnotationConfigApplicationContext也是BeanFactory的一个实现类。
但是,运行上述代码,System.out.println(context == bean.beanFactory);的输出结果为false。
这是不是意味着,在容器中,ApplicationContext和BeanFactory是两个不同的实例对象呢?
BeanFactory 和 ApplicationContext
在AnnotationConfigApplicationContext中有一个getBeanFactory方法。
准确来说,是org.springframework.context.support.AbstractApplicationContext#getBeanFactory。
@Configurable
public class Main {
@Autowired
BeanFactory beanFactory;
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
Main bean = context.getBean(Main.class);
// false
System.out.println(context == bean.beanFactory);
// true
System.out.println(context.getBeanFactory() == bean.beanFactory);
context.close();
}
}
AbstractApplicationContext是ApplicationContext的抽象实现。
AnnotationConfigApplicationContext继承了GenericApplicationContext,而GenericApplicationContext又继承了AbstractApplicationContext。

在AbstractApplicationContext中,所有BeanFactory接口的实现,都是委托给了BeanFactory对象。
// AbstractApplicationContext#getBean(java.lang.Class<T>, java.lang.Object...)
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType, args);
}
// AbstractApplicationContext#getBeanFactory
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
getBeanFactory()是一个抽象方法用。
GenericApplicationContext实现了该抽象方法:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
...
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
...
}
总结
ApplicationContext是BeanFactory的子接口,但是ApplicationContext的实例对象和BeanFactory的实例对象并不是同一个。
在ApplicationContext的实现中,有一个成员变量DefaultListableBeanFactory beanFactory,所有和BeanFactory接口相关的功能都是委派给这个成员变量来实现的。
ApplicationContext实现类中的beanFactory成员变量和容器中的BeanFactory才是同一个实例对象。
从源码角度来看BeanFactory和ApplicationContext的关系的更多相关文章
- Android布局性能优化—从源码角度看ViewStub延迟加载技术
在项目中,难免会遇到这种需求,在程序运行时需要动态根据条件来决定显示哪个View或某个布局,最通常的想法就是把需要动态显示的View都先写在布局中,然后把它们的可见性设为View.GONE,最后在代码 ...
- Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签
写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...
- Spring源码学习之BeanFactory体系结构
一.BeanFactory BeanFactory是Spring IOC容器的鼻祖,是IOC容器的基础接口,所有的容器都是从它这里继承实现而来.可见其地位.BeanFactory提供了最基本的IOC容 ...
- 从源码角度深入理解Toast
Toast这个东西我们在开发中经常用到,使用也很简单,一行代码就能搞定: 1: Toast.makeText(", Toast.LENGTH_LONG).show(); 但是我们经常会遇到这 ...
- Android -- 带你从源码角度领悟Dagger2入门到放弃
1,以前的博客也写了两篇关于Dagger2,但是感觉自己使用的时候还是云里雾里的,更不谈各位来看博客的同学了,所以今天打算和大家再一次的入坑试试,最后一次了,保证最后一次了. 2,接入项目 在项目的G ...
- Android -- 带你从源码角度领悟Dagger2入门到放弃(二)
1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...
- 从源码角度入手实现RecyclerView的Item点击事件
RecyclerView 作为 ListView 和 GridView 的替代产物,相信在Android界已广为流传. RecyclerView 本是不会有类似 ListView 的那种点击事件,但是 ...
- 从template到DOM(Vue.js源码角度看内部运行机制)
写在前面 这篇文章算是对最近写的一系列Vue.js源码的文章(https://github.com/answershuto/learnVue)的总结吧,在阅读源码的过程中也确实受益匪浅,希望自己的这些 ...
- Android -- 带你从源码角度领悟Dagger2入门到放弃(一)
1,以前的博客也写了两篇关于Dagger2,但是感觉自己使用的时候还是云里雾里的,更不谈各位来看博客的同学了,所以今天打算和大家再一次的入坑试试,最后一次了,保证最后一次了. 2,接入项目 在项目的G ...
随机推荐
- Flex AIR自定义Mobile的弹出框组件
做Flex Mobile开发的人应该知道,Flex为手机应用并没有提供弹出框组件,需要自定义. 通过查找文档.资料,我做出一个效果还算不错的弹出框组件,可以适用于手机设备上,不多讲,直接贴源码,相信对 ...
- nginx——前端服务环境
背景:之前一直使用tomcat服务器来作为测试环境:(vue项目打包后想测试下生产环境下有没有问题!使用tomcat有各种问题,还怀疑是我们源码有问题?尴尬)今天公司同事才告诉我tomcat是专门为j ...
- 【codeforces 764B】Timofey and cubes
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- Vmware虚拟机用户密码忘记了怎么办?
Vmware虚拟机用户密码忘记了怎么办? 虚拟机Linux上用户密码忘记了怎么办? 今天准备再学习一下linux操作系统,由于之前已经安装过vaware和linux(redhat),所以这次认为不 ...
- js基础——变量、作用域、内存
1.new关键字创建的是引用类型: eg. var box = new Object(); box.name = "Linda";//引用类型添加属性没问题 al ...
- springboot配置大全
此配置大全是在官方开发者文档中看到的,地址:https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/html/common-ap ...
- 2018.11.16 浪在ACM 集训队第五次测试赛
2018.11.16 浪在ACM 集训队第五次测试赛 整理人:李继朋 Problem A : 参考博客:[1]朱远迪 Problem B : 参考博客: Problem C : 参考博客:[1]马鸿儒 ...
- 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之Tarjan算法)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...
- git 上传当前分支
因为我现在的分支是的名很长,每次需要上次当前分支需要写很多代码,是不是有很简单方法上传当前分支. 如果要上传一个分支到仓库 origin 那么就需要使用下面的命令 git push origin 分支 ...
- FreeSql配合仓储实现软删除
该篇内容由个人博客点击跳转同步更新!转载请注明出处! 前段时间使用FreeSql作为ORM,写了一个简单的CMS,在这里总结一下其中的使用心得. 仓储配合全局过滤器 1. 统一的删除标志 如:数据库字 ...