AbstractApplicationContext.refresh()
来源:互联网 发布:理想禁区 知乎 编辑:程序博客网 时间:2024/06/06 00:48
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 为刷新工作做一些当前上下文 context 上的准备工作 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // ApplicationContext 实现了 BeanFactory 接口,但是并非直接作为 Bean 容器。 // ApplicationContext 中真正直接作为 Bean 容器的是一个内部Bean工厂 BeanFactory, // 通过其方法 getBeanFactory() 得到,此方法在 AbstractApplicationContext 中 // 被声明为 abstract, 其实现要求由实现子类提供。下面的语句 obtainFreshBeanFactory() // 内部就是通过调用 getBeanFactory() 获得这个内部 Bean 工厂的。 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 准备当前上下文使用的Bean容器 BeanFactory,设置其标准上下文特征,比如类加载器等 // 1. BeanFactory 的类加载器设置为当前上下文的类加载器 // 2. BeanFactory 的Bean表达式解析器设置为 new StandardBeanExpressionResolver() // 3. BeanFactory 增加 BeanPostProcessror new ApplicationListenerDetector(this) // 4.三个单例Bean被注册 : environment,systemProperties,systemEnvironment prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 在当前上下文使用的Bean容器BeanFactory的标准初始化完成后对其做一些修改。此时 // 所有的Bean definition都已经加载但是还没有 Bean 被创建。 // 当前上下文使用的Bean容器 BeanFactory 的 post process // 1.当前上下文是 EmbeddedWebApplicationContext 时, // 这个步骤中会对 beanFactory 注册一个 BeanPostProcessor : // WebApplicationContextServletContextAwareProcessor // 2.当前上下文是 AnnotationConfigEmbeddedWebApplicationContext 时, // 如果设置了 basePackages, // 这里会使用 AnnotatedBeanDefinitionReader扫描basePackages; // 如果设置了 annotatedClasses, // 这里会使用 ClassPathBeanDefinitionScanner登记annotatedClasses; postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 在 beanFactory 上调用 BeanFactoryPostProcessors, // 当前上下文可能会有多个 BeanFactoryPostProcessor 需要应用在 beanFactory 上 // **************************************************************** // 这里需要尤其注意区别 BeanFactoryPostProcessor 和 BeanPostProcessor // BeanFactoryPostProcessor : 作用在 Bean定义 上,用来定制修改 Bean定义 // BeanPostProcessor :作用在 Bean实例 上,用来修改或者包装 Bean实例 // **************************************************************** // 该方法实际上将实现委托出去 : // PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册 BeanPostProcessor // 该步骤实际工作委托给工具类 PostProcessorRegistrationDelegate 的静态方法 // void registerBeanPostProcessors( // ConfigurableListableBeanFactory beanFactory, // AbstractApplicationContext applicationContext) registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. // 初始化当前上下文ApplicationContext要使用的 事件多播器 // ApplicationEventMulticaster applicationEventMulticaster。 // // 如果容器中已经注册类型为ApplicationEventMulticaster并且名称为 // applicationEventMulticaster 的Bean,则直接使用;否则, // 新建一个SimpleApplicationEventMulticaster实例并注册到 // Bean容器,Bean名称使用 applicationEventMulticaster。 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // AbstractApplicationContext 中 onRefresh() 方法实现为空,其目的就是 // 留给实现子类一个机会做一些上下文相关的刷新工作。在一些特殊Bean初始化时,单 // 例 singleton Bean 初始化之前该方法被调用。 // 1. 当前上下文是 EmbeddedWebApplicationContext 时,该步骤会创建一个 // 内置的 Servlet 容器, 具体参考 EmbeddedWebApplicationContext 的 // 方法 void createEmbeddedServletContainer() onRefresh(); // Check for listener beans and register them. // 1. 将外部指定到当前上下文的 ApplicationListener 实例关联到上下文多播器 // Q : 什么时候外部给当前上下文指定 ApplicationListener ? // A : 举例说明,Springboot 应用 SpringApplication 的情况下,是在 // prepareContext()结尾时SpringApplicationRunListeners的 // contextLoaded() 调用中发生的,此时正在广播事件 // ApplicationPreparedEvent // 2. 将实现了 ApplicationListener 接口的所有 Bean 关联到上下文多播器 // 3. 如果上下文属性earlyApplicationEvents中有要通知的事件,广播出去 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 完成 BeanFactory 的初始化工作 // 1.BeanFactory冻结所有的Bean定义:不再可以修改或者做post process操作 // 2.确保所有的non-lazy-init单例Bean被初始化,也包括FactoryBean // 3.如果所初始化的单例Bean实现了接口SmartInitializingSingleton,调用 // 其方法 afterSingletonsInstantiated() finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 1. 初始化生命周期处理器 LifecycleProcessor, 使用已经存在的Bean或者 // 一个新的DefaultLifecycleProcessor实例; // 2. 生命周期处理器 LifecycleProcessor 上传播 refresh 事件 // 3. 发布事件 ContextRefreshedEvent // 4. 如果存在 LiveBeansView MBean 的话,关联到当前上下文 // 当前上下文是EmbeddedWebApplicationContext的情况下,还会: // 5. 启动EmbeddedServletContainer,比如启动内置 tomcat容器 // 6. 发布事件 EmbeddedServletContainerInitializedEvent finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
参考资料 : PostProcessorRegistrationDelegate 的介绍
阅读全文
0 0
- AbstractApplicationContext.refresh()
- Spring源码阅读--AbstractApplicationContext refresh()方法调用
- AbstractApplicationContext
- AbstractApplicationContext
- AbstractApplicationContext -> destroy()
- AbstractApplicationContext.invokeBeanFactoryPostProcessors()
- refresh
- structure-2-AbstractApplicationContext
- Spring源码学习--AbstractApplicationContext(八)
- Spring源码学习——AbstractApplicationContext
- Adodc.Refresh
- refresh 页面
- refresh iframe
- Refresh InfoPath
- refresh标签
- Refresh Memory
- ajxa refresh
- ddr sdram self-refresh & auto-refresh
- ADT- 双向链表
- win10 vmware 桥接网络连接问题
- 清除myeclipse中 Launch configuration的历史记录
- 数论 图论板子&&数据结构
- Windows下git连接GitHub(github.com)、码市(coding.net)、码云(gitee.com)
- AbstractApplicationContext.refresh()
- ES6-函数的扩展-双冒号运算符
- HTML 小技巧
- protege4.3安装使用
- Android 事件处理概述
- 欢迎使用CSDN-markdown编辑器
- JZOJ 5464 乘积
- centos7.2 grafana的安装与简单使用
- [视频处理]自译的ffmpeg ./configure参数