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

  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