1.1 Spring測試環境搭建
Spring模組概覽,綠色是模組,Spring中八大模組,黑色表示該模組包含的jar包(元件)。例如我們想要用IOC容器,也就是綠色的CoreContainer,我們需要匯入Beans,Core,Context,SpEL(spring-expression)四個包。
Spring模組概覽
Test:測試相關Core Container:IOC容器AOP:面向切面程式設計Aspects:切面Instrumenttation:跟JDK關聯,一般不用Messaging:訊息服務,一般不用Data Access/Integration:資料訪問與整合(JDBC訪問,Transaction事務,ORM物件關係對映,OXM和XML對映一般不用,JMS為Java訊息服務Java-message-service一般不用)Web:Web服務(WebSocket網路通訊協議,Servlet, Web,Portlet一般不用)最偷懶的方式,是直接匯入Spring-Framework。但是可能匯入不必要的包,導致專案打包後比較大
由於Spring-Content中的ApplicationContent是整個IOC的入口。我們匯入Spring-context包即可
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.2.3.RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
新建Spring配置檔案spring.xml:
import com.xiaodai.service.Hello;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); Hello hello = applicationContext.getBean("hello", Hello.class); System.out.println(hello.getName()); }}
1.2 Debug容器建立過程從測試類的new ClassPathXmlApplicationContext("spring.xml")開始debug,進入ClassPathXmlApplicationContext,可以看到:
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); // 設定配置檔案路徑 setConfigLocations(configLocations); if (refresh) { // 核心步驟 refresh(); } }
載入配置檔案後,進入refresh()方法,該方法是容器初始化的核心步驟。該方法包含十三個方法:
@Override 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容器,實質就是獲取工廠。 * 載入xml等配置檔案,用該檔案產生的BeanDefinition來建立一個工廠 **/ 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. // 後置增強,方便擴充套件 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 例項化並且執行BeanFactoryPostProcessors invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 例項化並且註冊所有的BeanPostProcessor registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 國際化設定,一般用不到 initMessageSource(); // Initialize event multicaster for this context. // 初始化應用程式的多波器和廣播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 空方法,預留給子類做擴充套件 onRefresh(); // Check for listener beans and register them. // 註冊監聽器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 工作中常用,面試常問。例項化所有非懶載入的例項物件 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 完成重新整理 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(); } } }
1.3 AbstractApplicationContext的refresh()包含的13個方法分析結合概覽圖一個一個方法分析:
Bean工廠例項化Bean概覽圖
方法1:prepareRefresh() => 準備工作準備重新整理,做一些最基本的準備化工作
protected void prepareRefresh() { // Switch to active. // 設定開始時間 this.startupDate = System.currentTimeMillis(); // 關閉狀態設定為false this.closed.set(false); // 活躍狀態設定為true this.active.set(true); // 列印日誌 if (logger.isDebugEnabled()) { if (logger.isTraceEnabled()) { logger.trace("Refreshing " + this); } else { logger.debug("Refreshing " + getDisplayName()); } } // 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<>(); }
總結:1.設定啟動事件 2.設定關閉活躍的狀態 3.獲取環境物件並設定屬性值 4.設定監聽器以及需要釋出事件的集合。
重要的點:
獲取環境資訊,驗證屬性資訊,getEnvironment().validateRequiredProperties();儲存預重新整理的一些應用資訊的監聽器,在Spring中是空實現,但是SpringBoot中,是有具體的值的方法2:obtainFreshBeanFactory() => 獲得一個重新整理的bean容器獲得一個重新整理的bean容器,實質就是獲取工廠。建立容器物件DefaultListableBeanFactory;載入xml配置檔案的屬性到當前的工廠中,最重要的就是BeanDefinition
Bean工廠例項繼承關係圖
AbstractRefreshableApplicationContext:
// 只要進到這個方法,那麼我們建立的一定是一個新的工廠 @Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { // 如果存在先銷燬,後關閉 destroyBeans(); closeBeanFactory(); } try { // 建立bean工廠,這裡使用的就是DefaultListableBeanFactory。此時建立的工廠裡面的屬性值都是預設值 DefaultListableBeanFactory beanFactory = createBeanFactory(); // 序列化id beanFactory.setSerializationId(getId()); // 設定一些屬性值 customizeBeanFactory(beanFactory); // 載入bean的定義屬性值。該方法有很多過載,非常複雜,核心是do操作 // 完成配置檔案或者配置類檔案的載入 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
方法3:prepareBeanFactory(beanFactory) => 準備(初始化)Bean工廠為方法2拿到的工廠,設定某些具體的值
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. // 為bean工廠設定類載入器 beanFactory.setBeanClassLoader(getClassLoader()); // 設定SPEL解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. // 新增一個BeanPostProcessor 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. // MessageSource registered (and found for autowiring) as a 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新增一個BeanPostProcessor增強器 ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. 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()); } }
方法4:postProcessBeanFactory(beanFactory) => 後置增強Bean(擴充套件實現)空方法,方便擴充套件
方法5:invokeBeanFactoryPostProcessors(beanFactory) => 執行BFPP例項化並且執行BeanFactoryPostProcessors
/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. * 單例物件之前一定呼叫,因為單例bean建立後就只有一份 */ 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())); } }
方法6:registerBeanPostProcessors(beanFactory) => 註冊BPP例項化並且註冊所有的BeanPostProcessor。例項化Bean之前的準備工作
/** * Instantiate and register all BeanPostProcessor beans, * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
方法7:initMessageSource() => 國際化設定方法8:initApplicationEventMulticaster() => 初始化應用程式的多波器和廣播器也屬於準備工作
方法9:onRefresh() => 預留給子類做擴充套件空方法
方法10:registerListeners() => 註冊監聽器也屬於準備工作
/** * Add beans that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. */ protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! 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... Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
方法11:finishBeanFactoryInitialization(beanFactory) => 例項化所有單例物件面試常問,工作常用。過程比較複雜
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. /** * 把型別轉化操作,設定到當前的beanFactory裡面去 **/ if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. /** * 判斷當前的beanFactory有沒有內建的值處理器 **/ if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. /** * 織入Aware **/ String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. // 設定類載入器 beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. /** * 凍結:某些bean不需要進行修改操作了,放入 **/ beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. /** * 例項化所有非懶載入的例項物件(重要) **/ beanFactory.preInstantiateSingletons(); }
例項化所有非懶載入的例項物件方法:
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. /** * 拿到所有註冊bean的名稱 **/ List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // 迴圈去建立我們需要的單例物件 for (String beanName : beanNames) { // 拿到bean的定義資訊,就是我們在xml配置檔案裡面指定的一些屬性 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 是否是抽象的,是否是單例的,是否是懶載入的 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 判斷當前類是否實現了factoryBean介面。一般沒實現,直接進入下面的getBean if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { // 透過beanName。拿到bean getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
重要方法:
createBeanInstance => 核心的建立和例項化bean的過程,由doCreateBean呼叫大量的反射出現在該方法中,用來建立物件
/** * Create a new instance for the specified bean, using an appropriate instantiation strategy: * factory method, constructor autowiring, or simple instantiation. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a BeanWrapper for the new instance * @see #obtainFromSupplier * @see #instantiateUsingFactoryMethod * @see #autowireConstructor * @see #instantiateBean */ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Candidate constructors for autowiring? // 構造器 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. /** * 預設無參構造 **/ return instantiateBean(beanName, mbd); }
instantiateBean(beanName, mbd) => 預設無參構造 /** * Instantiate the given bean using its default constructor. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @return a BeanWrapper for the new instance */ protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> // 例項化只會分配記憶體空間,設定預設值 getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
instantiate @Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(bd, beanName, owner); } }
BeanUtils.instantiateClass => 透過構造器反射建立bean /** * Convenience method to instantiate a class using the given constructor. * <p>Note that this method tries to set the constructor accessible if given a * non-accessible (that is, non-public) constructor, and supports Kotlin classes * with optional parameters and default values. * @param ctor the constructor to instantiate * @param args the constructor arguments to apply (use {@code null} for an unspecified * parameter, Kotlin optional parameters and Java primitive types are supported) * @return the new instance * @throws BeanInstantiationException if the bean cannot be instantiated * @see Constructor#newInstance */ public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { ReflectionUtils.makeAccessible(ctor); if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) { return KotlinDelegate.instantiateClass(ctor, args); } else { Class<?>[] parameterTypes = ctor.getParameterTypes(); Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters"); Object[] argsWithDefaultValues = new Object[args.length]; for (int i = 0 ; i < args.length; i++) { if (args[i] == null) { Class<?> parameterType = parameterTypes[i]; argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null); } else { argsWithDefaultValues[i] = args[i]; } } return ctor.newInstance(argsWithDefaultValues); } } catch (InstantiationException ex) { throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); } catch (IllegalAccessException ex) { throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); } catch (IllegalArgumentException ex) { throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); } catch (InvocationTargetException ex) { throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); } }
方法12:finishRefresh() => 完成重新整理 /** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */ 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. getLifecycleProcessor().onRefresh(); // Publish the final event. publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
方法13:resetCommonCaches() => 快取重置 /** * Reset Spring's common reflection metadata caches, in particular the * {@link ReflectionUtils}, {@link AnnotationUtils}, {@link ResolvableType} * and {@link CachedIntrospectionResults} caches. * @since 4.2 * @see ReflectionUtils#clearCache() * @see AnnotationUtils#clearCache() * @see ResolvableType#clearCache() * @see CachedIntrospectionResults#clearClassLoader(ClassLoader) */ protected void resetCommonCaches() { ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
最後回顧整個流程概覽圖: