专栏首页用户4352451的专栏ApplicationContext 和beanFactory 和 factoryBean的区别以及联系

ApplicationContext 和beanFactory 和 factoryBean的区别以及联系

背景

最近有看一些面试题,很多框架都有提到三者的关系和区别。所以今天打算看一下。

简单描述

beafactory是Spring IOC中的基础容器,用来解析BeanDefination存放bean的容器,还会对外提供一些操作bean的接口,AplicationContext是BeanFactory的扩展容器,基于BeanFactory 将其和其他组件整合到了一起。而factoryBean是以bean结尾的我们就可以知道它是以bean结尾的,所以我们可以认为他是一个特殊的bean,可以用来生产bean的一个bean,有点绕口。

beanFactory

  1. BeanFactory是IOC容器的顶层方法,他也可以说是SpringIOC容器之一吧(另一个就是他的扩展容器ApplicationContext)。
  2. 先看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);
}
  1. BeanFactory只是一个对外暴露的接口,而具体的实现有很多种 如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。 都是附加了某种功能的实现。 它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能。 也可以这么说吧,BeanFactory就是Spring的基础容器对外暴露的接口。
  2. 我们再来看看实现这个接口的类都有哪些

FactoryBean

  1. 看看源码和使用。
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;
        }
    }
  1. 其实我一直不能理解这个FactoryBean到底是想干什么的,于是大概想了一下。且最终结果是现在大家都在使用SpringBoot还有Spring的注解。已经真的很难感受到之前xml注册bean的繁琐了。所以真的是深切的体会不到FactoryBean使用的便捷。虽然FactoryBean在框架里面有被实现和使用70多种但是在平时的开发也不会遇到这些东西,所以真的是感觉到尤为陌生。
  2. 一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean。在某些情况下,实例化bean过程复杂,则就需要我们书写xml文件,在中书写大量的配置信息,配置的方式的灵活性是受限的,这个时候采用编码的方式会得到一个相对简单的解决方案,那就是通过FactoryBean来创建这个bean(FactoryBean也是一个Bean,他的特殊之处是可以生产bean.把她想成一个女人,bean是人类)其实也可以想成工厂方法的装饰器模式。
  3. 还有就是FactoryBean在AOP中的使用,我们知道AOP实际上是Spring在运行时创建了一个代理对象,也就是说这个对象,是我们在运行时创建的,而不是一开始就定义好的,这很符合工厂方法模式。更形象地说,AOP代理对象通过Java的反射机制,在运行时创建了一个代理对象,在代理对象的目标方法中根据业务要求织入了相应的方法。这个对象在Spring中就是——ProxyFactoryBean。 所以,FactoryBean为我们实例化Bean提供了一个更为灵活的方式,我们可以通过FactoryBean创建出更为复杂的Bean实例。

ApplicationContext

还有结合上面的依赖图可知:

  1. 如果说BeanFactory是Spring的心脏,那么ApplicationContext就是完整的躯体了,ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置实现。
  2. BeanFactorty接口提供了配置框架及基本功能,但是无法支持spring的aop功能和web应用。而ApplicationContext接口作为BeanFactory的派生,因而提供BeanFactory所有的功能。而且ApplicationContext还在功能上做了扩展,相较于BeanFactorty,ApplicationContext还提供了以下的功能:
  • MessageSource, 提供国际化的消息访问
  • 资源访问,如URL和文件
  • 事件传播特性,即支持aop特性
  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
  1. 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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • BigDecimal大小判断

    equals源码: public boolean equals(Object anObject) {//name2传入equals方法,anObject指向n...

    居士
  • HTTP错误代码

    200:正确的请求返回正确的结果,如果不想细分正确的请求结果都可以直接返回200。 201:表示资源被正确的创建。比如说,我们 POST 用户名、密码正确创建...

    居士
  • 【LeetCode】把字符串 s 中的每个空格替换成““%20””day02

    原题地址:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/

    居士
  • python str转bool方法

    py3study
  • 「R」MacOS 安装 R4.0

    前往 https://mirrors.tuna.tsinghua.edu.cn/CRAN/ 下载新的版本,鼠标点击安装。

    王诗翔呀
  • 再看JavaScript,那些遗漏或易混淆的知识点(1)

    , 运算符优先级相当的低,比 = 还低。所以,这里使用括号包裹。使用括号包裹以后,会选择括号中的最后一个元素作为括号运算的返回值。

    踏浪
  • 带你看看飞思卡尔工程自动生成神器

    精彩内容 飞思卡尔的工程自动生成器可以快速建立基于SDK的工程,让用户快速建立评估工程,提高开发速度,那么如何使用工程自动生成神器呢,今天就带来精彩内容 简介 ...

    用户1605515
  • 首届腾讯犀牛鸟创新人才培养研讨会举行

    近年来,在移动互联网发展大潮下,校企如何协同进行创新人才培养,提前锁定最精锐的人才,成为公司非常关注的问题。高校作为培养人才、传承知识、创新科技的主要阵地,对培...

    腾讯高校合作
  • Palantir与美政府再度合作推出新冠病毒疫苗追踪系统,数据隐私担忧再被提及

    数据报道,曾经成功找到本·拉登的美国大数据公司Palantir这次的任务是帮助美国的卫生部门监控疫苗。据《华尔街日报》报道,Palantir正帮助美国联邦政府建...

    数据猿
  • PHP中的反射

    PHP5 具有完整的反射 API,添加了对类、接口、函数、方法和扩展进行反向工程的能力。 此外,反射 API 提供了方法来取出函数、类和方法中的文档注释。 ...

    Enjoy233

扫码关注云+社区

领取腾讯云代金券