大家好,我是小黑,这是年前的最后一篇推文,提前祝大家新年快乐~~
这次我们从源码角度来聊聊 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
才是同一个实例对象。