你们好,我是小黑,这是年前的最后一篇推文,提早祝你们新年快乐~~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)ide
Event publicationui
Application-layer specific contexts such as the
WebApplicationContext
for use in web applications.this
从官方文档能够了解到:code
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
才是同一个实例对象。