首先我们先来看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的扩展
- 如果以上说法有误还请各位大佬指出,这只是我个人理解以及学习笔记