Spring中BeanFactory与ApplicationContext的关系

首先我们先来看BeanFactory与ApplicationContext的UML图(继承关系)

BeanFactory与ApplicationContext的UML图
从图上可以看出,ApplicationContext继承了BeanFactory,也就是说ApplicationContext是BeanFactory的子类,那么它们之间有什么区别呢?下面通过一个简单的例子来说明:

public class DependencyInjectionDemo {
    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:自己的xml路径");
        User user = beanFactory.getBean("user", User.class);
        System.out.println(beanFactory == user.getBeanFactory());//输出false
    }
}
public class User {
	//依赖注入
    @Autowired
    private BeanFactory beanFactory;
    
    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
}

经测试发现,上面的输出语句为false。
那么问题来了,既然说ApplicationContext是BeanFactory的子类,那么输出语句应该是true才对,那么这里为什么会出现false呢?

我们再来输入出这两个对象:

System.out.println(beanFactory);
System.out.println(userRepository.getBeanFactory());

输出的结果为

org.springframework.context.support.ClassPathXmlApplicationContext@1a6c5a9e, started on Sat Jul 03 14:22:22 CST 2021
org.springframework.beans.factory.support.DefaultListableBeanFactory@2f686d1f: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,userRepository]; root of factory hierarchy

可以看出,在我们自己创建的beanFactory为ClassPathXmlApplicationContext,而依赖注入的beanFactory为DefaultListableBeanFactory(也是beanFactory的唯一实现),那么是为什么呢?

我们深入源码去看

首先我们知道,ClassPathXmlApplicationContext继承于AbstractApplicationContext(这里不过多赘述),因此我们直接找到AbstractApplicationContext里的getBean方法:

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

这里出现了个getBeanFactory(),我们再看看这个getBeanFactory()是什么:

@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
@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;
	}
}

这里我们追到了AbstractRefreshableApplicationContext这个类,而且这个类继承了AbstractApplicationContext,并实现了getBeanFactory()这个方法

在这个方法里我们看到,AbstractRefreshableApplicationContext它返回了个this.beanFactory,我们再看看看这个beanFactory是什么东西:

@Nullable
private DefaultListableBeanFactory beanFactory;

可以看出,这个beanFactory就是DefaultListableBeanFactory,也就是我们上文所提到的DefaultListableBeanFactory。为了加以验证,我们将一开始的代码稍加改造:

public class DependencyInjectionDemo {
    public static void main(String[] args) {
        ApplicationContext beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");
        UserRepository userRepository = beanFactory.getBean(UserRepository.class);
        //方法源码在下面
        System.out.println(beanFactory.getAutowireCapableBeanFactory() == userRepository.getBeanFactory());
    }
}
@Override
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
	return getBeanFactory();
}

此时控制台输出了true,就证明了AbstractRefreshableApplicationContext里的beanFactory就是我们依赖注入的beanFactory。

总结

  • ApplicationContext是BeanFactory的子类,并且与beanFactory是组合的关系。并且每次getBean()底层都是依赖BeanFactory来进行依赖查找
  • BeanFactory是IOC的底层,提供了最基本的方法。而ApplicationContext是beanFactory的派生,提供了许多beanFactory所不能完成的功能,同时也拥有BeanFactory的所有功能,是对BeanFactory的扩展
  • 如果以上说法有误还请各位大佬指出,这只是我个人理解以及学习笔记
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值