Spring核心编程思想(十八)Spring IoC 容器概述之BeanFactory 和 ApplicationContext 谁才是 Spring IoC 容器

小马哥课程笔记

BeanFactory 和 ApplicationContext 谁才是 Spring IoC 容器?

这个表达式为什么不会成立
   userRepository.getBeanFactory() == beanFactory  is false
   这是因为 ApplicationContext is BeanFactory
/**
 * 依赖注入示例
 * 可以发现BeanFactory不是一个普通的Bean 通过依赖注入可以获得但是又不和通过上下文获取的beanFactory相等  通过依赖查找无法获得
 * 此处的beanFactory和applicationContext相等
 *
 * @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
 * @since
 */
public class DependencyInjectionDemo {

    public static void main(String[] args) {
        // 配置 XML 配置文件
        // 启动 Spring 应用上下文
//        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");

        // 依赖来源一:自定义 Bean
        UserRepository userRepository = applicationContext.getBean("userRepository", UserRepository.class);

//        System.out.println(userRepository.getUsers());

        // 依赖来源二:依赖注入(內建依赖)
        System.out.println(userRepository.getBeanFactory());

        //延时注入
        ObjectFactory userFactory = userRepository.getObjectFactory();

        System.out.println(userFactory.getObject() == applicationContext);

        // 依赖查找(错误)
//        System.out.println(beanFactory.getBean(BeanFactory.class));

        // 依赖来源三:容器內建 Bean (这是Environment 抽象,是外部化配置和profile的综合体)
        Environment environment = applicationContext.getBean(Environment.class);
        System.out.println("获取 Environment 类型的 Bean:" + environment);
    }

    private static void whoIsIoCContainer(UserRepository userRepository, ApplicationContext applicationContext) {


        // ConfigurableApplicationContext <- ApplicationContext <- BeanFactory

        // ConfigurableApplicationContext#getBeanFactory()


        // 这个表达式为什么不会成立
        System.out.println(userRepository.getBeanFactory() == applicationContext);

        // ApplicationContext is BeanFactory

    }

}
来自于官网的对于BeanFactory和ApplicationContext的阐述
 ApplicationContext is sub-interface of BeanFactory

在这里插入图片描述

一种设计模式
  1. 代码中new ClassPathXmlApplicationContext() 得到的是 ClassPathXmlApplicationContext
  2. 在ClassPathXmlApplicationContext 向上查看继承关系 它实现了ConfigurableApplicationContext 这是一个可配置的接口
  3. ConfigurableApplicationContext 又继承了 ApplicationContext
    ApplicationContext 又继承了 BeanFactory
  4. 所以ConfigurableApplicationContext 它本身就是一个 BeanFactory
  5. 但是它本身还是提供了一个 ConfigurableListableBeanFactory getBeanFactory() 的方法;
  6. 而且它还有一个void setParent(@Nullable ApplicationContext parent)方法
  7. 然后查看getBeanFactory的AbstractRefreshableApplicationContext实现类中的getBeanFactory方法
/** Bean factory for this context. */
	@Nullable
	private DefaultListableBeanFactory beanFactory;

@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		synchronized (this.beanFactoryMonitor) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("BeanFactory not initialized or already closed - " +
						"call 'refresh' before accessing beans via the ApplicationContext");
			}
			return this.beanFactory;
		}
	}
  1. 可以发现beanFactory 这里是一个组合,AbstractRefreshableApplicationContext是把DefaultListableBeanFactory 组合进来了而不是通过继承,这里有点类似代理模式.
    这里也是userRepository.getBeanFactory() == beanFactory is false的原因,他们毕竟是两个对象(BeanFactory 和 DefaultListableBeanFactory ).
  2. 然后再来看getBean的实现,相当于就是利用了DefaultListableBeanFactory 代理的BeanFactory去获得Bean
@Override
	public <T> T getBean(Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType);
	}
  1. 最后可以得出一个结论,BeanFactory是一个底层的IoC容器,ApplicationContext 是在这基础上增加了一些特性,并且ApplicationContext 是BeanFactory完整的超集,BeanFactory拥有的ApplicationContext 也全都拥有
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值