|
| 1 | + |
| 2 | + |
| 3 | +### 框架Refresh方法解析一 |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +#### 1.Refresh方法简介 |
| 8 | + |
| 9 | +- Bean配置读取加载入口 |
| 10 | +- Spring框架的启动流程 |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | +#### 2.Refresh方法的执行步骤 |
| 15 | + |
| 16 | +<img src="https://tva1.sinaimg.cn/large/008i3skNly1gvib55enehj61eg0u041602.jpg" alt="image-20211017144834689" align="left" width="800" /> |
| 17 | + |
| 18 | +```java |
| 19 | + @Override |
| 20 | + public void refresh() throws BeansException, IllegalStateException { |
| 21 | + synchronized (this.startupShutdownMonitor) { |
| 22 | + // Prepare this context for refreshing. |
| 23 | + // 准备此上下文 |
| 24 | + prepareRefresh(); |
| 25 | + |
| 26 | + // Tell the subclass to refresh the internal bean factory. |
| 27 | + // 获取BeanFacotry |
| 28 | + ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); |
| 29 | + |
| 30 | + // Prepare the bean factory for use in this context. |
| 31 | + // 准备此类上下文中使用的Bean工厂 |
| 32 | + prepareBeanFactory(beanFactory); |
| 33 | + |
| 34 | + try { |
| 35 | + // Allows post-processing of the bean factory in context subclasses. |
| 36 | + // 允许在上下文子类中对Bean工厂进行后处理 |
| 37 | + postProcessBeanFactory(beanFactory); |
| 38 | + |
| 39 | + // Invoke factory processors registered as beans in the context. |
| 40 | + // 调用在上下文中注册为Bean的工厂处理器 |
| 41 | + invokeBeanFactoryPostProcessors(beanFactory); |
| 42 | + |
| 43 | + // Register bean processors that intercept bean creation. |
| 44 | + // 注册拦截Bean创建的Bean处理器 |
| 45 | + registerBeanPostProcessors(beanFactory); |
| 46 | + |
| 47 | + // Initialize message source for this context. |
| 48 | + // 为此上下文初始化消息源 |
| 49 | + initMessageSource(); |
| 50 | + |
| 51 | + // Initialize event multicaster for this context. |
| 52 | + // 为此上下文初始化事件广播器 |
| 53 | + initApplicationEventMulticaster(); |
| 54 | + |
| 55 | + // Initialize other special beans in specific context subclasses. |
| 56 | + // 初始化特定上下文子类中的其他特殊Bean |
| 57 | + onRefresh(); |
| 58 | + |
| 59 | + // Check for listener beans and register them. |
| 60 | + // 检查监听器,并注册 |
| 61 | + registerListeners(); |
| 62 | + |
| 63 | + // Instantiate all remaining (non-lazy-init) singletons. |
| 64 | + // 实例化所有剩余的(非延迟初始化)单例。 |
| 65 | + finishBeanFactoryInitialization(beanFactory); |
| 66 | + |
| 67 | + // Last step: publish corresponding event. |
| 68 | + // 最后一步:发布相应的事件 |
| 69 | + finishRefresh(); |
| 70 | + } |
| 71 | + |
| 72 | + catch (BeansException ex) { |
| 73 | + if (logger.isWarnEnabled()) { |
| 74 | + logger.warn("Exception encountered during context initialization - " + |
| 75 | + "cancelling refresh attempt: " + ex); |
| 76 | + } |
| 77 | + |
| 78 | + // Destroy already created singletons to avoid dangling resources. |
| 79 | + // 销毁已经创建的单例以避免浪费资源 |
| 80 | + destroyBeans(); |
| 81 | + |
| 82 | + // Reset 'active' flag. |
| 83 | + // 重置active标志 |
| 84 | + cancelRefresh(ex); |
| 85 | + |
| 86 | + // Propagate exception to caller. |
| 87 | + throw ex; |
| 88 | + } |
| 89 | + |
| 90 | + finally { |
| 91 | + // Reset common introspection caches in Spring's core, since we |
| 92 | + // might not ever need metadata for singleton beans anymore... |
| 93 | + // 重置 Spring 核心中的常见内省缓存,因为我们可能不再需要单例 bean 的元数据... |
| 94 | + resetCommonCaches(); |
| 95 | + } |
| 96 | + } |
| 97 | + } |
| 98 | +``` |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +#### 3.准备上下文:prepareRefersh#方法 |
| 103 | + |
| 104 | +- prepareRefersh#方法简介 |
| 105 | + - 清除本地元数据缓存 |
| 106 | + - 准备框架上下文 |
| 107 | + - 设置框架启动时间 |
| 108 | + - 设置框架 active 启动状态为true |
| 109 | + - 如果是Debug模式打印Debug日志 |
| 110 | + - 初始化环境配置 |
| 111 | + - 获取当前环境配置 |
| 112 | + - 如果是Web环境,配置ServletContext 和 ServletConfig |
| 113 | + - 检查环境配置中的必备属性是否存在 |
| 114 | + - 如果没有早期的事件监听器,就注册应用监听器:applicationListeners |
| 115 | + |
| 116 | +- prepareRefresh#方法 |
| 117 | + |
| 118 | +```java |
| 119 | + @Override |
| 120 | + protected void prepareRefresh() { |
| 121 | + // 清除元数据缓存 |
| 122 | + this.scanner.clearCache(); |
| 123 | + // 准备上下文 |
| 124 | + super.prepareRefresh(); |
| 125 | + } |
| 126 | +``` |
| 127 | + |
| 128 | +- clearCache#方法 |
| 129 | + |
| 130 | +```java |
| 131 | + /** |
| 132 | + * Clear the local metadata cache, if any, removing all cached class metadata. |
| 133 | + * 清除本地元数据缓存(如果有),删除所有缓存的类元数据。 |
| 134 | + */ |
| 135 | + public void clearCache() { |
| 136 | + if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { |
| 137 | + // Clear cache in externally provided MetadataReaderFactory; this is a no-op |
| 138 | + // for a shared cache since it'll be cleared by the ApplicationContext. |
| 139 | + // 清除外部提供的 MetadataReaderFactory 中的缓存;这是一个无操作用于共享缓存,因为它将被 ApplicationContext 清除。 |
| 140 | + ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); |
| 141 | + } |
| 142 | + } |
| 143 | +``` |
| 144 | + |
| 145 | +- super.prepareRefresh方法 |
| 146 | + |
| 147 | +```java |
| 148 | + /** |
| 149 | + * Prepare this context for refreshing, setting its startup date and |
| 150 | + * active flag as well as performing any initialization of property sources. |
| 151 | + * 准备此上下文以进行刷新、设置其启动日期和* active 标志以及执行属性源的任何初始化 |
| 152 | + */ |
| 153 | + protected void prepareRefresh() { |
| 154 | + // Switch to active. |
| 155 | + // 设置启动时间 |
| 156 | + this.startupDate = System.currentTimeMillis(); |
| 157 | + this.closed.set(false); |
| 158 | + // 设置 active 标志状态为 true |
| 159 | + this.active.set(true); |
| 160 | + |
| 161 | + // 如果当前日志状态是Debug模式的话,会打印一段话 |
| 162 | + if (logger.isDebugEnabled()) { |
| 163 | + if (logger.isTraceEnabled()) { |
| 164 | + logger.trace("Refreshing " + this); |
| 165 | + } |
| 166 | + else { |
| 167 | + logger.debug("Refreshing " + getDisplayName()); |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + // Initialize any placeholder property sources in the context environment. |
| 172 | + // 初始化环境配置 |
| 173 | + initPropertySources(); |
| 174 | + |
| 175 | + // Validate that all properties marked as required are resolvable: |
| 176 | + // see ConfigurablePropertyResolver#setRequiredProperties |
| 177 | + // 检查环境属性中必备的环境数据,如果没有就 throw MissingRequiredPropertiesException 异常 |
| 178 | + getEnvironment().validateRequiredProperties(); |
| 179 | + |
| 180 | + // Store pre-refresh ApplicationListeners... |
| 181 | + // 将系统的事件监听器进行注册 |
| 182 | + if (this.earlyApplicationListeners == null) { |
| 183 | + this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); |
| 184 | + } |
| 185 | + else { |
| 186 | + // Reset local application listeners to pre-refresh state. |
| 187 | + this.applicationListeners.clear(); |
| 188 | + this.applicationListeners.addAll(this.earlyApplicationListeners); |
| 189 | + } |
| 190 | + |
| 191 | + // Allow for the collection of early ApplicationEvents, |
| 192 | + // to be published once the multicaster is available... |
| 193 | + this.earlyApplicationEvents = new LinkedHashSet<>(); |
| 194 | + } |
| 195 | + |
| 196 | +``` |
| 197 | + |
| 198 | +- initPropertySources#方法 |
| 199 | + |
| 200 | +```java |
| 201 | + protected void initPropertySources() { |
| 202 | + // 获取环境配置上下文 |
| 203 | + ConfigurableEnvironment env = this.getEnvironment(); |
| 204 | + // 如果当前环境是Web环境,将servletContext 和 ServletConfig 加载到环境配置上下文中 |
| 205 | + if (env instanceof ConfigurableWebEnvironment) { |
| 206 | + ((ConfigurableWebEnvironment)env).initPropertySources(this.servletContext, (ServletConfig)null); |
| 207 | + } |
| 208 | + } |
| 209 | +``` |
| 210 | + |
| 211 | + |
| 212 | + |
| 213 | + |
| 214 | + |
| 215 | +#### 获取新的Bean工厂:obtainFreshBeanFacotry#方法 |
| 216 | + |
| 217 | +- obtainFreshBeanFacotry#方法简介 |
| 218 | + - 设置当前上下文刷新状态为true |
| 219 | + - 这是BeanFactory序列化ID(默认是application) |
| 220 | + - 返回BeanFacotry |
| 221 | + |
| 222 | +- obtainFreshBeanFactory#方法 |
| 223 | + |
| 224 | +```java |
| 225 | + /** |
| 226 | + * Tell the subclass to refresh the internal bean factory. |
| 227 | + * 告诉子类刷新内部 bean 工厂 |
| 228 | + * @return the fresh BeanFactory instance |
| 229 | + * @see #refreshBeanFactory() |
| 230 | + * @see #getBeanFactory() |
| 231 | + */ |
| 232 | + protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { |
| 233 | + // 设置上下文刷新状态和Beanfacotory的序列化ID |
| 234 | + refreshBeanFactory(); |
| 235 | + // 获取BeanFactory(默认是DefaultListableBeanFacotry) |
| 236 | + return getBeanFactory(); |
| 237 | + } |
| 238 | + |
| 239 | +``` |
| 240 | + |
| 241 | +- refreshBeanFacoty#方法 |
| 242 | + |
| 243 | +```java |
| 244 | + /** |
| 245 | + * Do nothing: We hold a single internal BeanFactory and rely on callers |
| 246 | + * to register beans through our public methods (or the BeanFactory's). |
| 247 | + * @see #registerBeanDefinition |
| 248 | + */ |
| 249 | + @Override |
| 250 | + protected final void refreshBeanFactory() throws IllegalStateException { |
| 251 | + // 设置当前上下文刷新状态:true |
| 252 | + if (!this.refreshed.compareAndSet(false, true)) { |
| 253 | + throw new IllegalStateException( |
| 254 | + "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once"); |
| 255 | + } |
| 256 | + // 设置BeanFacotry序列化ID:默认是application |
| 257 | + this.beanFactory.setSerializationId(getId()); |
| 258 | + } |
| 259 | +``` |
| 260 | + |
| 261 | +- getBeanFacotory#方法 |
| 262 | + |
| 263 | +```java |
| 264 | +/** |
| 265 | + * Return the single internal BeanFactory held by this context |
| 266 | + * (as ConfigurableListableBeanFactory). |
| 267 | + */ |
| 268 | + @Override |
| 269 | + public final ConfigurableListableBeanFactory getBeanFactory() { |
| 270 | + // 返回默认的 DefaultListableBeanFacotry |
| 271 | + return this.beanFactory; |
| 272 | + } |
| 273 | +``` |
| 274 | + |
| 275 | + |
| 276 | + |
0 commit comments