温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

ApplicationContext和XmlBeanFactory有哪些区别

发布时间:2021-10-13 10:43:46 来源:亿速云 阅读:129 作者:iii 栏目:编程语言

这篇文章主要讲解了“ApplicationContext和XmlBeanFactory有哪些区别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ApplicationContext和XmlBeanFactory有哪些区别”吧!

ApplicationContext和XmlBeanFactory的区别

在ApplicationContext的源码解析中,这些推测还能使用吗?答案是可以的。之前我们聊过IOC容器的设计与实现,无非就是两个系列,一个BeanFactory,一个ApplicationContext。那么我们之前看的XmlBeanFactory属于哪一种类呢?先来看一下XmlBeanFactory的类图 ApplicationContext和XmlBeanFactory有哪些区别

XmlBeanFactory继承体系是 XmlBeanFactory -> DefaultListableBeanFactory -> AbstractAutowireCapableBeanFactory -> AbstractBeanFactory -> FactoryBeanRegistrySupport -> DefaultSingletonBeanRegistry -> SimpleAliasRegistry -> AliasRegistry

但是请注意:XmlBeanFactory是在DefaultListableBeanFactory的基础上做扩展的。其实最终还是实现了BeanFactory接口。而我们的ApplicationContext,它是做为一种容器的高级形态存在。应用上下文,在简单的容器上增加了许多其他的特性。为什么这么说呢?我们来看看ApplicationContext的类图。

ApplicationContext和XmlBeanFactory有哪些区别

不难发现ApplicationContext其实也是实现了BeanFactory,但是这里可以明显的看到,ApplicationContext做了更多的支持。

BeanFactory

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的区别在哪

ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
    super(parent);
    this.setConfigLocations(configLocations);
    if (refresh) {
        this.refresh();
    }
}

它的初始化在不断的调用super(parent),但是refresh()方法完成了容器的初始化。

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有哪些区别这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI