咱們仍是從 SpringApplication.run(String... args)
看起。程序員
// SpringApplication # run(String... args) # 311-313 public ConfigurableApplicationContext run(String... args) { // ………… prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); // ………… return context; }
咱們進入 refreshContext(context)
方法體中:web
// SpringApplication # refreshContext(ConfigurableApplicationContext context) # 390 private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } } }
很顯然,核心方法仍是去調用了 refresh(context):面試
// SpringApplication # refresh(ApplicationContext applicationContext) # 742 protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) applicationContext).refresh(); }
繼續進入((AbstractApplicationContext) applicationContext).refresh()
:緩存
// AbstractApplicationContext # refresh() # 515 public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 爲刷新容器,準備上下文 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 告訴子類刷新內部bean工廠 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 準備在此上下文使用的bean工廠。 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 容許在上下文子類中對bean工廠進行後處理 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 調用在上下文中註冊爲bean的工廠處理器。 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 註冊攔截Bean建立的Bean處理器。 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 初始化此上下文的消息源。 initMessageSource(); // Initialize event multicaster for this context. // 爲上下文,初始化事件廣播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 在特定上下文子類中初始化其餘特殊bean。 onRefresh(); // Check for listener beans and register them. // 檢查監聽器並註冊。 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 實例化全部剩餘的(非延遲初始化)單例。 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 發佈相應的事件。 finishRefresh(); } // ………… }
方法註釋:準備此上下文以進行刷新,設置其啓動日期和活動標誌以及執行屬性源的任何初始化。session
protected void prepareRefresh() { // 設置啓動日期、活動標誌 this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); // ………… // Initialize any placeholder property sources in the context environment. // 初始化屬性設置 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties // 驗證必備屬性 getEnvironment().validateRequiredProperties(); // Store pre-refresh ApplicationListeners... // 保存刷新前的監聽器 if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }
// AbstractApplicationContext # obtainFreshBeanFactory() # 635 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); }
這個方法比較簡單,作了兩件事:併發
此方法,主要設置 從obtainFreshBeanFactory()
獲取到的 beanFacotory
的各類屬性。app
方法註釋:配置工廠的標準上下文特徵,例如上下文的ClassLoader和後處理器ide
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. // 告訴內部bean工廠使用上下文的類加載器等。 beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. // 使用上下文回調配置Bean工廠。 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 配置忽略的依賴關係 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // BeanFactory接口未在普通工廠中註冊爲可解析類型。 // MessageSource registered (and found for autowiring) as a bean. // MessageSource註冊爲Bean(並發現用於自動裝配)。 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. // 註冊早期的後處理器以將內部bean檢測爲ApplicationListeners。 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. // 檢測LoadTimeWeaver,並準備進行織入(若是找到)。 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. // 設置一個臨時的ClassLoader以進行類型匹配。 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. // 註冊默認環境Bean。 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
此方法,作了如下幾件事:post
這裏是一個空實現,留給子類重寫。能夠在 beanFactory 完成建立後作進一步設置。學習
對於 Servlet 而言,就是設置一些做用域之類的,例如 request、session 等。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
這裏的主要邏輯在 invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
:
這個方法體太長了,就不貼出來了。主要作了兩件事:
調用BeanDefinitionRegistryPostProcessor
實現向容器內添加bean的定義。
其實這裏咱們在上一小節實踐過了,下面就是咱們添加的 Bean 。
@Componentpublic class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setBeanClass(MyTwoBean.class); beanDefinitionRegistry.registerBeanDefinition("myTwoBean",rootBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { }}
調用BeanFactoryPostProcessor
實現向容器內添加bean的定義添加屬性。
這個方法和invokeBeanFactoryPostProcessors(beanFactory)
是相似的。
找到BeanPostPocessor的實現,排序後註冊進容器內。
主要是國際化、多語言配置。
不是重點,略過。
初始化事件廣播器。監聽器相關內容,咱們以前已經學習過。此處也是相似的。
// 當前有監聽器就用監聽器;沒有的話,就新建一個。protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); } }
子類實現。Servlet 下主要表現爲建立 web 容器。
// ServletWebServerApplicationContext # onRefresh() # 150protected void onRefresh() { super.onRefresh(); try { createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } }
咱們知道super.onRefresh()
是空實現,因此直接看createWebServer()
:
// 這個方法就是:建立容器的方法。咱們暫不深究。private void createWebServer() { WebServer webServer = this.webServer; ServletContext servletContext = getServletContext(); if (webServer == null && servletContext == null) { ServletWebServerFactory factory = getWebServerFactory(); this.webServer = factory.getWebServer(getSelfInitializer()); } else if (servletContext != null) { try { getSelfInitializer().onStartup(servletContext); } catch (ServletException ex) { throw new ApplicationContextException("Cannot initialize servlet context", ex); } } initPropertySources(); }
protected void registerListeners() { // Register statically specified listeners first. // 首先註冊靜態指定的偵聽器。 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 把容器中 listenerBean 註冊 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... // 當Bean沒加載完時,事件是發佈不出去的,因此暫時保存在earlyApplicationEvents中 // 到此時,再把攢下的事件發佈出去。 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
實例化BeanFactory 中已經被註冊可是沒被實例化的全部實例。
這是比較重要的 Bean 實例化流程。因此咱們後面單開一節來學習。
因此,暫時不過多探究源碼了。
protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). // 清除資源緩存 clearResourceCaches(); // Initialize lifecycle processor for this context. // 初始化生命週期處理器(非學習重點) initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. // 生命週期處理器的 onRefresh() ,也是非學習重點。 getLifecycleProcessor().onRefresh(); // Publish the final event. // 發佈容器已刷新事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. // 非學習重點。 LiveBeansView.registerApplicationContext(this);}
此方法在 finally {} 中被調用,作一些清除緩存的工做。
protected void resetCommonCaches() { ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
至此,refresh 方法咱們已通過了一遍。
這一小節,仍是着重於 refresh 的整體流程。對於一些細節,留待之後慢慢學習,一口又吃不成個大胖子。
最近我整理了整套《JAVA核心知識點總結》,說實話 ,做爲一名Java程序員,不論你需不須要面試都應該好好看下這份資料。拿到手老是不虧的~個人很多粉絲也所以拿到騰訊字節快手等公司的Offer
進【Java進階之路羣】,找管理員獲取哦-!