Spring 的启动过程
本文的目的是记录自己在学习 Spring 容器启动过程中的一些笔记, 以供后面复习, 也希望可以给有需要的朋友提供一点帮助. 本次分析所用的 Spring 版本为 5.1.4.RELEASE.
首先我们从容器创建为入口, 逐渐深入容器的启动过程.
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
上面这行代码大家应该都很熟悉, 通过这行代码就可以完成 IoC 容器的初始化, 让 Spring 帮我们管理一切. 下面我们就从 AnnotationConfigApplicationContext 这个类开始, 一层一层解开 Spring 的神秘面纱.
- public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
- /**
- 此处只是初始化了 Bean Definition 的 reader 和 scanner
- this.reader = new AnnotatedBeanDefinitionReader(this);
- this.scanner = new ClassPathBeanDefinitionScanner(this);
- */
- this();
- // 此处只是将传进来的配置类(AppConfig.class 注册到 BeanDefinitionMap 中去)
- register(annotatedClasses);
- // 重点在 refresh 方法里面
- refresh();
- }
在前两个方法中只是做了简单的初始化 IoC 容器所需的对象, 此时 IoC 容器是空的, 通过 refresh 方法会一次来解析 beandefinition 并产生对象装入容器中, 下面来分析 refresh 方法.
- // Prepare this context for refreshing.
- // 这个方法只是记录了容器启动时间, 设置容器为 active 状态, 并无实际操作, 不重要.
- prepareRefresh();
- // Tell the subclass to refresh the internal bean factory.
- // 此处只是给 Bean Factory 设置了一个 SerializationId
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- // Prepare the bean factory for use in this context.
- // 初始化了 IoC 容器的一些工具, 比如 Class Loader,EL 表达式解析器和属性解析器
- prepareBeanFactory(beanFactory);
- // Allows post-processing of the bean factory in context subclasses.
- // 空方法
- postProcessBeanFactory(beanFactory);
- // Invoke factory processors registered as beans in the context.
- // 执行所有的 BeanFactoryPostProcessor
- // 在 ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法会对所有的配置类进行处理, 通过 ConfigurationClassParser 对象来解析, 最终通过 parser.parse(candidates); 来调用解析方法.
- // 其中会处理所有 @Configuration 注解的类, 解析其配置的 @Bean 和 @ComponentScan 注解, 将相关的 Bean 扫描并加入到 BeanDefinitionMaps 中, 之后会使用动态代理 (CGLIB) 增强 Configuration 类, 增强是直接修改 Bean Definition 中 BeanClass 属性, 直接替换为代理后的 class
- invokeBeanFactoryPostProcessors(beanFactory);
- // 注册了两个 BeanPostProcessor, 一个 CommonBeanPostProcessor, 另一个 AutoWiredBeanPostProcessor, 注意, 这个后置处理器很重要, 他是完成自动装配的关键!
- // Register bean processors that intercept bean creation.
- registerBeanPostProcessors(beanFactory);
- // Initialize message source for this context.
- // 像 BeanFactory 注册了 messageSource
- initMessageSource();
- // Initialize event multicaster for this context.
- // 向 BeanFactory 注册了 applicationEventMulticaster
- initApplicationEventMulticaster();
- // Initialize other special beans in specific context subclasses.
- // 空方法, API 注释中写的是允许子类添加一些特定的逻辑在实例化单例 Bean 之前. before instantiation of singletons.
- onRefresh();
- // Check for listener beans and register them.
- // 将实现了 ApplicationListener 的类注册到 applicationEventMulticaster 中
- registerListeners();
- // Instantiate all remaining (non-lazy-init) singletons.
- // 实例化 Bean DefinitionMap 中所有的非懒加载的单例 Bean
- // 前面做大堆准备工作, 最终会冻结配置, 防止配置发生变化 (freezeConfiguration), 结束后调用 preInstantiateSingletons() 方法来实例化, 由于实例化较为重要, 下面单独分析 preInstantiateSingletons 方法
- finishBeanFactoryInitialization(beanFactory);
- // Last step: publish corresponding event.
- // 结束启动过程, 会清空在初始化过程中创建的一些缓存, 同时调用 LifecycleProcessor#onRefresh 方法. 最后会发布 ContextRefreshedEvent 事件.
- finishRefresh();
以上就是 Spring 启动的全过程, 后面我们会深入分析容器的初始化过程, 容器如何解析配置类, 如何根据配置类来实例化单例对象等.
由于本人水平有限, 难免遇到表述不清或错误的情况, 如果存在任何问题, 请大家及时提醒, 我会在第一时间进行修正.
来源: http://www.jianshu.com/p/a0aad8b452f1