夯实Spring系列|第四章:谁才是 Spring IoC 容器?

1.本章说明

本章主要讨论 BeanFactoryApplicationContext 谁才是 Spring IoC 容器?

2.验证

2.1 示例

本例中通过userRepository.getBeanFactory()获取这个 BeanFactory 对象与 main()方法中的 beanFactory 进行比较。

/**
 * 依赖注入示例
 */
public class DependencyInjectionDemo {
    public static void main(String[] args) {
        //配置 xml 配置文件
        //启动 spring 应用上下文
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml ");
        //自定义Bean
        UserRepository userRepository = beanFactory.getBean("userRepository", UserRepository.class);
        
        whoIsIocContainer(userRepository, beanFactory);
    }

    private static void whoIsIocContainer(UserRepository userRepository, BeanFactory beanFactory) {

        // ConfigurableApplicationContext -> ApplicationContext -> BeanFactory
        // 在上下文的实现中采用的是组合模式,org.springframework.context.support.AbstractRefreshableApplicationContext 中
        // 在接口的实现上又继承了 BeanFactory
        System.out.println("userRepository.getBeanFactory():" + userRepository.getBeanFactory());
        System.out.println("beanFactory:" + beanFactory);
        System.out.println("两者是否相等:" + (userRepository.getBeanFactory() == beanFactory));

    }

}

控制台输出结果

userRepository.getBeanFactory():org.springframework.beans.factory.support.DefaultListableBeanFactory@7b227d8d: defining beans [user,superUser,objectFactory,userRepository]; root of factory hierarchy
beanFactory:org.springframework.context.support.ClassPathXmlApplicationContext@7f690630, started on Fri Apr 17 21:53:16 CST 2020
两者是否相等:false

由结果可知两者并不相同。
那么DefaultListableBeanFactoryClassPathXmlApplicationContext这两个对象是什么关系?

2.2 Spring 官网其实对两者的关系做了一定的说明

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

  • Easier integration with Spring’s AOP features 集成Spring AOP 特性
  • Message resource handling (for use in internationalization) 国际化
  • Event publication 事件发布
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications. 应用级别的上下文,比如WEB应用使用的WebApplicationContext

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory

ApplicationContext 就是 BeanFactory,但是他们是两个不同的对象,BeanFactory 提供框架配置和基本功能,ApplicationContext 是 BeanFactory 的一个超集,一个子接口,ApplicationContext 提供更多的企业特性。

ApplicationContext 除了 IOC 容器角色,还提供

  • 面向切面 (AOP)
  • 配置元信息(Configuration Metadata)
  • 资源配置(Resource)
  • 事件(Events)
  • 国际化(i18n)
  • 注解(Annaotions)
  • Environment 抽象(Environment Abstraction)

2.3 源码分析

ApplicationContext 的层次关系比较复杂,我们直接定位到相关的类

  • org.springframework.context.support.AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

	@Nullable
	private Boolean allowBeanDefinitionOverriding;

	@Nullable
	private Boolean allowCircularReferences;

	/** Bean factory for this context. */
	@Nullable
	private DefaultListableBeanFactory beanFactory;
    ...
  • AbstractRefreshableApplicationContext 用组合的方式,获取到 BeanFactory 的默认实现 DefaultListableBeanFactory

  • 再看它的父类AbstractApplicationContext 中的 getBean()方法,其实是getBeanFactory()获取的这个 DefaultListableBeanFactory 对象,再调用 beanFactory.getBean(name) 方法来获取 Bean 对象,最终还是 BeanFactory 来获取 Bean 对象。

  • 由此可见,其实真正的底层 IoC 容器其实是 BeanFactory 。

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
	...
        
	//---------------------------------------------------------------------
	// Implementation of BeanFactory interface
	//---------------------------------------------------------------------

    @Override
	public Object getBean(String name) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name);
	}

	@Override
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, requiredType);
	}

	@Override
	public Object getBean(String name, Object... args) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, args);
	}
    ...

3.结论

  • ApplicationContext 是 BeanFactory 的一个超集,一个子接口;BeanFactory 提供框架配置和基本功能,ApplicationContext 提供更多的企业特性。

  • BeanFactory 才是真正的底层的 IoC 容器,因为 ApplicationContext 最终还是通过组合 BeanFactory 来实现 getBean() 方法

4.参考

  • 极客时间-小马哥《小马哥讲Spring核心编程思想》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值