你們好,我是小黑,這是年前的最後一篇推文,提早祝你們新年快樂~~html
此次咱們從源碼角度來聊聊BeanFactory
和ApplicationContext
的關係,講一些網上文章未曾提到的點。java
先來看一下官方文檔中關於BeanFactory
和ApplicationContext
的描述。web
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:spring
Easier integration with Spring’s AOP featuresapp
- Message resource handling (for use in internationalization)
- Event publication
Application-layer specific contexts such as the
WebApplicationContext
for use in web applications.idehttps://docs.spring.io/spring/docs/5.2.2.RELEASE/spring-framework-reference/core.html#beans-beanfactoryui
從官方文檔能夠了解到:this
BeanFactory
接口提供了可以管理任何類型對象的高級配置機制。code
ApplicationContext
是BeanFactory
的子接口,它增長了以下一些功能:htm
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
纔是同一個實例對象。