欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

从源码角度来看BeanFactory和ApplicationContext的关系

程序员文章站 2022-06-05 17:36:25
Spring容器中BeanFactory和ApplicationContext不是同一个实例对象??? ......

大家好,我是小黑,这是年前的最后一篇推文,提前祝大家新年快乐~~

这次我们从源码角度来聊聊beanfactoryapplicationcontext的关系,讲一些网上文章不曾提到的点。

官方描述

先来看一下官方文档中关于beanfactoryapplicationcontext的描述。

the org.springframework.beans and org.springframework.context packages are the basis for spring framework’s ioc container. the beanfactoryinterface 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 webapplicationcontext for use in web applications.

https://docs.spring.io/spring/docs/5.2.2.release/spring-framework-reference/core.html#beans-beanfactory

从官方文档可以了解到:

beanfactory接口提供了能够管理任何类型对象的高级配置机制。

applicationcontextbeanfactory的子接口,它增加了如下一些功能:

  • 更容易与 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();
    }
}

annotationconfigapplicationcontextapplicationcontext的一个实现类,换而言之,annotationconfigapplicationcontext也是beanfactory的一个实现类。

但是,运行上述代码,system.out.println(context == bean.beanfactory);的输出结果为false

这是不是意味着,在容器中,applicationcontextbeanfactory是两个不同的实例对象呢?

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();
    }
}

abstractapplicationcontextapplicationcontext的抽象实现。

annotationconfigapplicationcontext继承了genericapplicationcontext,而genericapplicationcontext又继承了abstractapplicationcontext

从源码角度来看BeanFactory和ApplicationContext的关系

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;
    }
    ...
}

总结

applicationcontextbeanfactory的子接口,但是applicationcontext的实例对象和beanfactory的实例对象并不是同一个。

applicationcontext的实现中,有一个成员变量defaultlistablebeanfactory beanfactory,所有和beanfactory接口相关的功能都是委派给这个成员变量来实现的。

applicationcontext实现类中的beanfactory成员变量和容器中的beanfactory才是同一个实例对象。