Spring的核心功能就是容器功能,用于存放bean的容器。这里有几个概念需要清楚:什么是容器什么又是bean?bean我们可以理解为系统中的类实例对象,而容器在Spring中就是BeanFactory的实现类。
1. 首先定义Spring容器
我们有两种方式配置Spring容器,一种是xml配置方式,一种是java配置方式(一般是结合使用)
// 1. xml配置方式初始化容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/beanFactoryTest.xml");
// 2. java配置方式初始化容器
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
这里容器为什么是ApplicationContext而不是我们上面说的BeanFactory呢,这里需要说明一下ApplicationContext和BeanFactory的区别:
BeanFactory: bean的工厂接口,提供了bean的基本获取方法,BeanFactory的接口关系如下:
ApplicationContext:应用上下文,继承自BeanFactory和其它接口,拥有自己的扩展功能如Environmentcapable和messagesource等(一般使用它)
在前面的示例中我们使用的是ClassPathXmlApplicatinContext和AnnotationConfigApplicationContext在下面的分析中我们以AnnotationConfigApplicationContext为例进行分析说明:
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
/* 1. 第一步调用默认构造器创建两个工具对象
* 注解bean定义阅读器
* this.reader = new AnnotatedBeanDefinitionReader(this);
* 类路径bean定义扫描器
* this.scanner = new ClassPathBeanDefinitionScanner(this);
*/
this();
// 2. 注册配置文件
register(annotatedClasses);
// 3. 刷新容器
refresh();
}
第一步为我们创建了阅读器和扫描器,第二步开始注册配置文件,最后一不是最为核心重要的步骤刷新容器。
第一步就不分析了,第二步注册配置文件简单分析一下:这一步其实就是调用了我们第一步创建的阅读器分析配置文件的所有注解信息,然后将注解信息定义对象注册到我们的注册中心(注册中心就是AnnotationConfigApplicationContext)
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
this.reader.register(annotatedClasses);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
// 拿到配置文件所有的注解信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
.....................
................................
// 将注解配置信息注册到我们的注册中心(ApplicationContext)
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
第三步refresh()也是最核心的一步:在这一步中完成了Spring容器和bean的所有构建工作,具体细分为下面几步
// 1. 预处理---> 刷新前的预处理工作
prepareRefresh();
// 2. 预处理----> 获取bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 预处理----> bean工厂使用前预处理
prepareBeanFactory(beanFactory);
// 4. 预处理----->bean工厂后置处理器(留给子类实现)
postProcessBeanFactory(beanFactory);
// 5. 执行后置BeanFactory的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册Bean后置处理器
registerBeanPostProcessors(beanFactory);
// 7. 初始化消息组件
initMessageSource();
// 8.初始化应用事件派发器
initApplicationEventMulticaster();
// 9. 初始化其它组件(留给子类扩展)
onRefresh();
// 10.注册监听器
registerListeners();
// 11.实例化所有其它非lazy的bean
finishBeanFact