前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从源码角度来看 BeanFactory 和 ApplicationContext 的关系

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

作者头像
Coder小黑
发布2020-01-16 11:29:53
4380
发布2020-01-16 11:29:53
举报
文章被收录于专栏:Coder小黑Coder小黑

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

这次我们从源码角度来聊聊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 版本。

代码语言:javascript
复制
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver
代码语言:javascript
复制
public interface ListableBeanFactory extends BeanFactory

从源码可以证实到,ApplicationContext继承了BeanFactory

代码语言:javascript
复制
@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

代码语言:javascript
复制
@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

image.png

AbstractApplicationContext中,所有BeanFactory接口的实现,都是委托给了BeanFactory对象。

代码语言:javascript
复制
// 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);
}
代码语言:javascript
复制
// AbstractApplicationContext#getBeanFactory
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

getBeanFactory()是一个抽象方法用。

GenericApplicationContext实现了该抽象方法:

代码语言:javascript
复制
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才是同一个实例对象。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coder小黑 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 官方描述
  • 源码简析
    • BeanFactory 和 ApplicationContext
    • 总结
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档