这篇文章主要讲解了“ApplicationContext和XmlBeanFactory有哪些区别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ApplicationContext和XmlBeanFactory有哪些区别”吧!
在ApplicationContext的源码解析中,这些推测还能使用吗?答案是可以的。之前我们聊过IOC容器的设计与实现,无非就是两个系列,一个BeanFactory,一个ApplicationContext。那么我们之前看的XmlBeanFactory属于哪一种类呢?先来看一下XmlBeanFactory的类图
XmlBeanFactory继承体系是 XmlBeanFactory -> DefaultListableBeanFactory -> AbstractAutowireCapableBeanFactory -> AbstractBeanFactory -> FactoryBeanRegistrySupport -> DefaultSingletonBeanRegistry -> SimpleAliasRegistry -> AliasRegistry
但是请注意:XmlBeanFactory是在DefaultListableBeanFactory的基础上做扩展的。其实最终还是实现了BeanFactory接口。而我们的ApplicationContext,它是做为一种容器的高级形态存在。应用上下文,在简单的容器上增加了许多其他的特性。为什么这么说呢?我们来看看ApplicationContext的类图。
不难发现ApplicationContext其实也是实现了BeanFactory,但是这里可以明显的看到,ApplicationContext做了更多的支持。
BeanFactory是Spring最核心的所在,很多面试题问Spring是什么?其实就可以直接回答:Spring其实就是一个BeanFactory的巨大封装,当然好像有点片面,BeanFactory确确实实是Spring最核心的内容。
BeanFactory提供的是最基本的IOC容器的功能,关于这些功能,我们可以来读一下他的源码
String FACTORY_BEAN_PREFIX = "&"; /** * 根据名称获取bean */ Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; /** * 是否包含bean */ boolean containsBean(String name); /** * 查询bean是否是Singleton类型 */ boolean isSingleton(String name) throws NoSuchBeanDefinitionException; /** * 查询bean是否是Prototype类型 */ boolean isPrototype(String name) throws NoSuchBeanDefinitionException; /** * 查询bean的class类型是否是特定的class类型 */ boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException; /** * 查询bean的class类型 */ Class<?> getType(String name) throws NoSuchBeanDefinitionException; /** * 查询bean的所有别名 */ String[] getAliases(String name);
其实它的代码并不多,但是它提供了使用IOC容器的规范。理解这些呢,有助于我们理解ApplicationContext,我们可以直接认为BeanFactory是一种简单的容器形式,而ApplicationContext它是一种高级的容器形式。
到这里,其实我们已经看到XmlBeanFactory和ApplicationContext的一些区别了。但是这里其实不是那么的明显。我们不妨再来看看那ApplicationContext它的实现类ClassPathXmlApplicationContext,也就是我们代码里面用的。它的一个源码和XmlBeanFactory的区别在哪
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); this.setConfigLocations(configLocations); if (refresh) { this.refresh(); } }
它的初始化在不断的调用super(parent),但是refresh()方法完成了容器的初始化。
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); // 准备工作 ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); // 获取ConfigurableListableBeanFactory最终的目的是DefaultListableBeanFactory this.prepareBeanFactory(beanFactory); // 准备bean工厂 try { this.postProcessBeanFactory(beanFactory); // 一个空的实现,注意这里的spring版本号为:5.3x this.invokeBeanFactoryPostProcessors(beanFactory); // 注册bean的工厂 this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); // Spring 从所有的 @Bean 定义中抽取出来了 BeanPostProcessor,然后都注册进 beanPostProcessors,等待后面的的顺序调用 注册BeanPostProcessor this.initApplicationEventMulticaster(); // 初始化事件监听多路广播器 this.onRefresh(); // 一个空的实现 this.registerListeners(); // 注册监听器 this.finishBeanFactoryInitialization(beanFactory); // 到了spring加载流程最复杂的一步,开始实例化所有的bd this.finishRefresh();// 刷新完成工作 } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } }
方法从总体上看 还算比较清晰 用几个大的方法高度概括了refresh()做了些什么。后面我们会详细来解读这些流程,这里仅做一个总结。
到这里位置,我们看到了ClassPathXmlApplicationContext的一个流程,和我们的XmlBeanFactory的区别相当的大,在我们之前的推测中,他应该先去加载xml,其实这里也做了,只是隐藏的比较深,在这个加载流程的第二部的具体内容里面,我们这里贴一下核心代码
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.refreshBeanFactory(); this.loadBeanDefinitions(beanFactory); protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); this.initBeanDefinitionReader(beanDefinitionReader); this.loadBeanDefinitions(beanDefinitionReader); }
其实bean的初始化和容器的初始化也在这个流程里面全部提现了,这个我们后面再讲,但是从我们总结的内容来看,其实和我们的推测是大差不差的,只是多了很多其他的东西而已。多出来的这些东西也正是我们两种容器实现的区别所在。
BeanFactory的基本实现提供了基本的IOC容器,ApplicaitonContext以高级形态出现,增加了很多附加功能。
XmlBeanFactory是我们BeanFactory一种最基本应用
XmlBeanFactory和ClassPathXmlApplicationContext都具备我们推测的流程,但是实现有所不同,而且具体流程上,两个区别很大
感谢各位的阅读,以上就是“ApplicationContext和XmlBeanFactory有哪些区别”的内容了,经过本文的学习后,相信大家对ApplicationContext和XmlBeanFactory有哪些区别这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。