大家好,我是小黑,这是年前的最后一篇推文,提前祝大家新年快乐~~
这次我们从源码角度来聊聊 BeanFactory 和 ApplicationContext 的关系,讲一些网上文章不曾提到的点。
先来看一下官方文档中关于 BeanFactory 和 ApplicationContext 的描述。
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:
WebApplicationContext
https://docs.spring.io/spring...
从官方文档可以了解到:
BeanFactory 接口提供了能够管理任何类型对象的高级配置机制。
ApplicationContext 是 BeanFactory 的子接口,它增加了如下一些功能:
WebApplicationContext
以下源码基于 Spring 5.0.13 版本。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver
public interface ListableBeanFactory extends BeanFactory
从源码可以证实到, ApplicationContext 继承了 BeanFactory 。
@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();
}
}
AnnotationConfigApplicationContext 是 ApplicationContext 的一个实现类,换而言之, AnnotationConfigApplicationContext 也是 BeanFactory 的一个实现类。
但是,运行上述代码, System.out.println(context == bean.beanFactory); 的输出结果为 false 。
这是不是意味着,在容器中, ApplicationContext 和 BeanFactory 是两个不同的实例对象呢?
在 AnnotationConfigApplicationContext 中有一个 getBeanFactory 方法。
准确来说,是 org.springframework.context.support.AbstractApplicationContext#getBeanFactory 。
@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();
}
}
AbstractApplicationContext 是 ApplicationContext 的抽象实现。
AnnotationConfigApplicationContext 继承了 GenericApplicationContext ,而 GenericApplicationContext 又继承了 AbstractApplicationContext 。
在 AbstractApplicationContext 中,所有 BeanFactory 接口的实现,都是委托给了 BeanFactory 对象。
// 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);
}
// AbstractApplicationContext#getBeanFactory public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
getBeanFactory() 是一个抽象方法用。
GenericApplicationContext 实现了该抽象方法:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
...
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
...
}
ApplicationContext 是 BeanFactory 的子接口,但是 ApplicationContext 的实例对象和 BeanFactory 的实例对象并不是同一个。
在 ApplicationContext 的实现中,有一个成员变量 DefaultListableBeanFactory beanFactory ,所有和 BeanFactory 接口相关的功能都是委派给这个成员变量来实现的。
ApplicationContext 实现类中的 beanFactory 成员变量和容器中的 BeanFactory 才是同一个实例对象。