從源碼角度來看 BeanFactory 和 ApplicationContext 的關係
- 2020 年 1 月 16 日
- 筆記
大家好,我是小黑,這是前年的最後一篇推文,提前祝大家新年快樂~~
這次我們從源碼角度來聊聊BeanFactory
和ApplicationContext
的關係,講一些網上文章不曾提到的點。
官方描述
先來看一下官方文檔中關於BeanFactory
和ApplicationContext
的描述。
The
org.springframework.beans
andorg.springframework.context
packages are the basis for Spring Framework』s IoC container. TheBeanFactory
interface provides an advanced configuration mechanism capable of managing any type of object.ApplicationContext
is a sub-interface ofBeanFactory
. It adds:
- Easier integration with Spring』s AOP features
- Message resource handling (for use in internationalization)
- Event publication
- Application-layer specific contexts such as the
WebApplicationContext
for use in web applications.
https://docs.spring.io/spring/docs/5.2.2.RELEASE/spring-framework-reference/core.html#beans-beanfactory
從官方文檔可以了解到:
BeanFactory
介面提供了能夠管理任何類型對象的高級配置機制。
ApplicationContext
是BeanFactory
的子介面,它增加了如下一些功能:
- 更容易與 Spring 的 AOP 集成
- 消息資源處理,用於國際化
- 事件發布
- 特定於應用程式層的上下文,如用於 web 應用程式的
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
是兩個不同的實例對象呢?
BeanFactory 和 ApplicationContext
在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
。

image.png
在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
才是同一個實例對象。