Spring refresh源碼解析

1.refresh()

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//調用容器準備刷新的方法,獲取容器的當時時間,同時給容器設置同步標識
			prepareRefresh();

	
			//創建beanFactory.主要是加載bean的信息,分爲定位,加載,註冊
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//爲BeanFactory配置容器特性,例如類加載器、事件處理器等
			prepareBeanFactory(beanFactory);

			try {
				//子類通過重寫父類來對BeanFactory創建並預準備完成以後做進一步設置
				postProcessBeanFactory(beanFactory);

				//調用所有註冊的BeanFactoryPostProcessor的Bean
				invokeBeanFactoryPostProcessors(beanFactory);

				//爲BeanFactory註冊BeanPost事件處理器.這是僅僅是註冊,調用在getbean的時候
				registerBeanPostProcessors(beanFactory);

				//初始化信息源,和國際化相關.
				initMessageSource();

				//初始化容器事件傳播器.
				initApplicationEventMulticaster();

				//調用子類的某些特殊Bean初始化方法
				onRefresh();

				//爲事件傳播器註冊事件監聽器.
				registerListeners();

				//初始化所有剩餘的單例Bean
				finishBeanFactoryInitialization(beanFactory);

				//初始化容器的生命週期事件處理器,併發布容器的生命週期事件
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				//銷燬已創建的Bean
				destroyBeans();

				//取消refresh操作,重置容器的同步標識.
				cancelRefresh(ex);

				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

2.prepareRefresh();

刷新前的預處理

protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// 初始化一些屬性設置,子類自定義個性化屬性設置方法
		initPropertySources();

		//校驗屬性合法性
		getEnvironment().validateRequiredProperties();

		// 保存容器一些早期事件
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

上面主要是對刷新前的預處理,

  1. initPropertySources() 初始化一些屬性設置,子類自定義個性化屬性設置方法
  2. getEnvironment().validateRequiredProperties();校驗屬性合法性
  3. this.earlyApplicationEvents = new LinkedHashSet<>();保存容器一些早期事件

3.obtainFreshBeanFactory()

主要是獲取BeanFactory.加載bean的信息,分爲定位,加載,註冊

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//這裏使用了委派設計模式,父類定義了抽象的refreshBeanFactory()方法,具體實現調用子類容器的refreshBeanFactory()方法
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

上面主要做了創建BeanFactory,子類容器的refreshBeanFactory()方法主要是對bean信息的定位,加載,註冊

4.prepareBeanFactory

這一部分是BeanFactory的預準備工作

//爲BeanFactory配置容器特性,例如類加載器、事件處理器等
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 設置bean的類加載器
		beanFactory.setBeanClassLoader(getClassLoader());
  	// 設置表達式解析器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
  //添加屬性編輯管理的小工具
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		//設置部分BeanPostProcessor-》ApplicationContextAwareProcessor
		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.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		//添加BeanPostProcessor-》ApplicationListenerDetector
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 添加編譯時候的AspejctJ
		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()));
		}

		// 給BeanFactory註冊一些能用的組件
		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());
		}
	}

這部分主要做了

  1. 設置bean的類加載器,表達式解析器,屬性編輯管理
  2. 設置部分BeanPostProcessor-》ApplicationContextAwareProcessor
  3. 設置忽略的自動裝備接口
  4. 註冊可以解析的自動裝配,可以在任何組件中自動注入
  5. 添加BeanPostProcessor-》ApplicationListenerDetector
  6. 添加編譯時候的AspejctJ
  7. 給BeanFactory註冊一些能用的組件-》Environment,SystemProperties,SystemEnvironment

5.postProcessBeanFactory

子類通過重寫父類來對BeanFactory創建並預準備完成以後做進一步設置

6.invokeBeanFactoryPostProcessors

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   // Invoke BeanDefinitionRegistryPostProcessors first, if any.
   Set<String> processedBeans = new HashSet<>();

   if (beanFactory instanceof BeanDefinitionRegistry) {
      BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
      List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();

      for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
         if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                  (BeanDefinitionRegistryPostProcessor) postProcessor;
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            registryProcessors.add(registryProcessor);
         }
         else {
            regularPostProcessors.add(postProcessor);
         }
      }

      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the bean factory post-processors apply to them!
      // Separate between BeanDefinitionRegistryPostProcessors that implement
      // PriorityOrdered, Ordered, and the rest.
      List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

      // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
      String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
         if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
         }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
      currentRegistryProcessors.clear();

      // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
      boolean reiterate = true;
      while (reiterate) {
         reiterate = false;
         postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
         for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName)) {
               currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
               processedBeans.add(ppName);
               reiterate = true;
            }
         }
         sortPostProcessors(currentRegistryProcessors, beanFactory);
         registryProcessors.addAll(currentRegistryProcessors);
         invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
         currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
   }

   else {
      // Invoke factory processors registered with the context instance.
      invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let the bean factory post-processors apply to them!
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
   for (String ppName : postProcessorNames) {
      if (processedBeans.contains(ppName)) {
         // skip - already processed in first phase above
      }
      else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
      }
      else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      }
      else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : orderedPostProcessorNames) {
      orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   sortPostProcessors(orderedPostProcessors, beanFactory);
   invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

   // Finally, invoke all other BeanFactoryPostProcessors.
   List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
   for (String postProcessorName : nonOrderedPostProcessorNames) {
      nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
   }
   invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

   // Clear cached merged bean definitions since the post-processors might have
   // modified the original metadata, e.g. replacing placeholders in values...
   beanFactory.clearMetadataCache();
}

上面主要是執行BeanFactoryPostProcessors.是BeanFactory的後置處理器.在BeanFactory初始化執行,bean未實例化之前.包含兩個接口BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor

  1. 先執行BeanDefinitionRegistryPostProcessor方法.
    • 獲取所有的BeanDefinitionRegistryPostProcessor
    • 先執行實現了PriorityOrdered優先接口的BeanDefinitionRegistryPostProcessor
    • 在執行實現了Ordered順序接口的BeanDefinitionRegistryPostProcessor
    • 最後執行普通的BeanDefinitionRegistryPostProcessor
  2. 在執行BeanFactoryPostProcessor的方法
    • 獲取所有的BeanFactoryPostProcessor
    • 先執行實現了PriorityOrdered優先接口的BeanFactoryPostProcessor
    • 在執行實現了Ordered順序接口的BeanFactoryPostProcessor
    • 最後執行普通的BeanFactoryPostProcessor

7.registerBeanPostProcessors

爲BeanFactory註冊BeanPost事件處理器.

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

上面主要是註冊BeanPostProcessor(Bean後置處理器)

不同接口類型的BeanPostProcessor在Bean創建前後的執行時機是不一樣的

主要流程

  1. 獲取所有BeanPostProcessor;後置處理器都可以默認通過PriorityOrdered、Ordered接口來執行優先級
  2. 先註冊PriorityOrdered優先級接口的BeanPostProcessor;把每一個BeanPostProcessor添加到BeanPostProcessor;
  3. 在註冊的Ordered接口
  4. 最後註冊沒有實現任何優先級接口的
  5. 最終註冊MergedBeanDefinitionPostProcessor
  6. 註冊一個ApplicationListenerDetector,在Bean創建完成後檢查是否是ApplicationListener,如果是this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);

8.initMessageSource()

protected void  initMessageSource() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
      this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
      // Make MessageSource aware of parent MessageSource.
      if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
         HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
         if (hms.getParentMessageSource() == null) {
            // Only set parent context as parent MessageSource if no parent MessageSource
            // registered already.
            hms.setParentMessageSource(getInternalParentMessageSource());
         }
      }
      if (logger.isDebugEnabled()) {
         logger.debug("Using MessageSource [" + this.messageSource + "]");
      }
   }
   else {
      // Use empty MessageSource to be able to accept getMessage calls.
      DelegatingMessageSource dms = new DelegatingMessageSource();
      dms.setParentMessageSource(getInternalParentMessageSource());
      this.messageSource = dms;
      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
      if (logger.isDebugEnabled()) {
         logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
               "': using default [" + this.messageSource + "]");
      }
   }
}

方法主要是初始化MessageSource組件(做國際化功能,消息綁定,消息解析)

  1. 獲取BeanFactory
  2. 看容器中是否有id爲messageSource的,類型是MessageSource的組件,如果有賦值給messageSource,如果沒有自己創建一個DelegatingMessageSource.
    MessageSource是取出國際化配置文件中的key的值;能按照區域信息獲取
  3. 把創建好的MessageSource註冊在容器中,以後獲取國際化配置文件的值的時候,可以自動注入MessageSource
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
	String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);

9.initApplicationEventMulticaster();

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);
      if (logger.isDebugEnabled()) {
         logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else {
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isDebugEnabled()) {
         logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
               APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
               "': using default [" + this.applicationEventMulticaster + "]");
      }
   }
}

上面流程主要是初始化時機派發期

  1. 獲取BeanFactory
  2. 從BeanFactory獲取applicationEventMulticaster
  3. 如果上一步沒有配置,創建一個SimpleApplicationEventMulticaster
  4. 將創建的ApplicationEventMulticaster添加到BeanFactory中,以後其他組件直接自動注入

10.onRefresh()

子類重寫這個方法,在容器刷新的時候可以自定義邏輯

11.registerListeners()

給容器中將所有項目的ApplicationListener註冊進來

  1. 從容器中拿到所有ApplicationListener
  2. 將每個監聽器添加到事件派發器
    getApplicationEventMulticaster().addApplicationListener(listener)
  3. 派發之前步驟產生的事件

12finishBeanFactoryInitialization(beanFactory);

初始化剩下的單實例bean

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  
   //在對某些Bean屬性進行轉換時使用
   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.
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   //爲了類型匹配,停止使用臨時的類加載器
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   //緩存容器中所有註冊的BeanDefinition元數據,以防被修改
   beanFactory.freezeConfiguration();

   //對配置了lazy-init屬性的單態模式Bean進行預實例化處理
   beanFactory.preInstantiateSingletons();
}


//對配置lazy-init屬性單態Bean的預實例化
	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("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.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			//獲取Bean的定義信息RootBeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//Bean不是抽象的,是單態模式的,且lazy-init屬性配置爲false
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//判斷是否是FactoryBean
				if (isFactoryBean(beanName)) {
					//FACTORY_BEAN_PREFIX=”&”,當Bean名稱前面加”&”符號
					//時,獲取的是產生容器對象本身,而不是容器產生的Bean.
					//調用getBean方法,觸發容器對Bean實例化和依賴注入過程
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					//標識是否需要預實例化
					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方法,觸發容器對Bean實例化和依賴注入過程
						getBean(beanName);
					}
				}
				else {
					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();
				}
			}
		}
	}

AbstractBeanFactory中的getBean

@Override
public Object getBean(String name) throws BeansException {
   //doGetBean纔是真正向IoC容器獲取被管理Bean的過程
   return doGetBean(name, null, null, false);
}

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		//根據指定的名稱獲取被管理Bean的名稱,剝離指定名稱中對容器的相關依賴
		//如果指定的是別名,將別名轉換爲規範的Bean名稱
		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		//先從緩存中取是否已經有被創建過的單態類型的Bean
		//對於單例模式的Bean整個IOC容器中只創建一次,不需要重複創建
		Object sharedInstance = getSingleton(beanName);
		//IOC容器創建單例模式Bean實例對象
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				//如果指定名稱的Bean在容器中已有單例模式的Bean被創建
				//直接返回已經創建的Bean
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//獲取給定Bean的實例對象,主要是完成FactoryBean的相關處理
			//注意:BeanFactory是管理容器中Bean的工廠,而FactoryBean是
			//創建創建對象的工廠Bean,兩者之間有區別
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			//緩存沒有正在創建的單例模式Bean
			//緩存中已經有已經創建的原型模式Bean
			//但是由於循環引用的問題導致實例化對象失敗
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			//對IOC容器中是否存在指定名稱的BeanDefinition進行檢查,首先檢查是否
			//能在當前的BeanFactory中獲取的所需要的Bean,如果不能則委託當前容器
			//的父級容器去查找,如果還是找不到則沿着容器的繼承體系向父級容器查找
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//當前容器的父級容器存在,且當前容器中不存在指定名稱的Bean
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				//解析指定Bean名稱的原始名稱
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					//委派父級容器根據指定名稱和顯式的參數查找
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					//委派父級容器根據指定名稱和類型查找
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			//創建的Bean是否需要進行類型驗證,一般不需要
			if (!typeCheckOnly) {
				//向容器標記指定的Bean已經被創建
				markBeanAsCreated(beanName);
			}

			try {
				//根據指定Bean名稱獲取其父級的Bean定義
				//主要解決Bean繼承時子類合併父類公共屬性問題
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				//獲取當前Bean所有依賴Bean的名稱
				String[] dependsOn = mbd.getDependsOn();
				//如果當前Bean有依賴Bean
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						//遞歸調用getBean方法,獲取當前Bean的依賴Bean
						registerDependentBean(dep, beanName);
						//把被依賴Bean註冊給當前依賴的Bean
						getBean(dep);
					}
				}

				// Create bean instance.
				//創建單例模式Bean的實例對象
				if (mbd.isSingleton()) {
					//這裏使用了一個匿名內部類,創建Bean實例對象,並且註冊給所依賴的對象
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//創建一個指定Bean實例對象,如果有父級繼承,則合併子類和父類的定義
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							//顯式地從容器單例模式Bean緩存中清除實例對象
							destroySingleton(beanName);
							throw ex;
						}
					});
					//獲取給定Bean的實例對象
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				//IOC容器創建原型模式Bean實例對象
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					//原型模式(Prototype)是每次都會創建一個新的對象
					Object prototypeInstance = null;
					try {
						//回調beforePrototypeCreation方法,默認的功能是註冊當前創建的原型對象
						beforePrototypeCreation(beanName);
						//創建指定Bean對象實例
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						//回調afterPrototypeCreation方法,默認的功能告訴IOC容器指定Bean的原型對象不再創建
						afterPrototypeCreation(beanName);
					}
					//獲取給定Bean的實例對象
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				//要創建的Bean既不是單例模式,也不是原型模式,則根據Bean定義資源中
				//配置的生命週期範圍,選擇實例化Bean的合適方法,這種在Web應用程序中
				//比較常用,如:request、session、application等生命週期
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					//Bean定義資源中沒有配置生命週期範圍,則Bean定義不合法
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						//這裏又使用了一個匿名內部類,獲取一個指定生命週期範圍的實例
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						//獲取給定Bean的實例對象
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		//對創建的Bean實例對象進行類型檢查
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

AbstractAutowireCapableBeanFactory中的createBean

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // Make sure bean class is actually resolved at this point, and
   // clone the bean definition in case of a dynamically resolved Class
   // which cannot be stored in the shared merged bean definition.
   //判斷需要創建的Bean是否可以實例化,即是否可以通過當前的類加載器加載
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }

   // Prepare method overrides.
   //校驗和準備Bean中的方法覆蓋
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      //如果Bean配置了初始化前和初始化後的處理器,則試圖返回一個需要創建Bean的代理對象
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      //創建Bean的入口
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException ex) {
      // A previously detected exception with proper bean creation context already...
      throw ex;
   }
   catch (ImplicitlyAppearedSingletonException ex) {
      // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   //封裝被創建的Bean對象
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = instanceWrapper.getWrappedInstance();
   //獲取實例化對象的類型
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   //調用PostProcessor後置處理器
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }

   // Eagerly cache singletons to be able to resolve circular references
   // even when triggered by lifecycle interfaces like BeanFactoryAware.
   //向容器中緩存單例模式的Bean對象,以防循環引用
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   if (earlySingletonExposure) {
      if (logger.isDebugEnabled()) {
         logger.debug("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      //這裏是一個匿名內部類,爲了防止循環引用,儘早持有對象的引用
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   //Bean對象的初始化,依賴注入在此觸發
   //這個exposedObject在初始化完成之後返回作爲依賴注入完成後的Bean
   Object exposedObject = bean;
   try {
      //將Bean實例對象封裝,並且Bean定義中配置的屬性值賦值給實例對象
      populateBean(beanName, mbd, instanceWrapper);
      //初始化Bean對象
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }

   if (earlySingletonExposure) {
      //獲取指定名稱的已註冊的單例模式Bean對象
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
         //根據名稱獲取的已註冊的Bean和正在實例化的Bean是同一個
         if (exposedObject == bean) {
            //當前實例化的Bean初始化完成
            exposedObject = earlySingletonReference;
         }
         //當前Bean依賴其他Bean,並且當發生循環引用時不允許新創建實例對象
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            //獲取當前Bean所依賴的其他Bean
            for (String dependentBean : dependentBeans) {
               //對依賴Bean進行類型檢查
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
            if (!actualDependentBeans.isEmpty()) {
               throw new BeanCurrentlyInCreationException(beanName,
                     "Bean with name '" + beanName + "' has been injected into other beans [" +
                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                     "] in its raw version as part of a circular reference, but has eventually been " +
                     "wrapped. This means that said other beans do not use the final version of the " +
                     "bean. This is often the result of over-eager type matching - consider using " +
                     "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
            }
         }
      }
   }

   // Register bean as disposable.
   //註冊完成依賴注入的Bean
   try {
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}
  1. beanFactory.preInstantiateSingletons();初始化剩下的單實例bean

    • 獲取容器中的所有Bean,依次進行初始化和創建對象

    • 獲取Bean的定義信息,RootBeanDefinition

    • Bean不是抽象的,是單實例的 ,懶加載爲false的

      • 判斷是否是FactoryBean;是否是FactoryBean接口的Bean

      • 不是工廠Bean,利用getBean(beanName)創建對象

        • 1.getBean(beanName)

        • 2.doGetBean(name, null, null, false)

        • 3.先獲取緩存中保存的單實例Bean,如果能獲取到說明這個Bea之前被創建過,所有創建過的單實例bean都會被保存到緩存中.private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

        • 4.緩存獲取不到,開始Bean的創建對象流程

        • 5.標記Bean已經被創建

        • 6.獲取Bean定義信息

        • 7.判斷當前Bean是否有依賴dependsOn其他bean ,如果有先創建出來(dependsOn配置)

        • 8.啓動單實例Bean的創建流程

          • 1.createBean
          • 2.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);讓BeanPostProcessors攔截生成代理對象,前提是(比較特殊的BeanPostProcessors,正常的都是bean實例化後調用BeanPostProcessors)
          • 3.如果前面InstantiationAwareBeanPostProcessor沒有返回代理對象,則繼續下一步,否則直接返回
          • 4.Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            • 1.createBeanInstance(beanName, mbd, args); 創建Bean實例,先判斷是否用調用工廠方法實例化,如果不是就使用構造方法實例,構造方法分爲有參跟無參實例,如果是無參構造再判斷Bean定義中沒有方法覆蓋,沒有就直接構造器反射創建.否則CGLIB父類類的方法
            • 2.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);創建實例後調用postProcessMergedBeanDefinition對bean實例完進行擴展,這個是BeanPostProcessorMergedBeanDefinitionPostProcessor(比較特殊beanPostProcessor)
            • 3.populateBean(beanName, mbd, instanceWrapper); 給對象賦值
              賦值之前
              • 1會先拿到InstantiationAwareBeanPostProcessor後置處理器的postProcessAfterInstantiation,
              • 2.在拿到InstantiationAwareBeanPostProcessor的postProcessPropertyValues
                ———————賦值之前—————————
              • 3.應用Bean屬性的值,爲屬性利用setter方法進行復制applyPropertyValues(beanName, mbd, bw, pvs);
            • 4.initializeBean
              • 1.執行invokeAwareMethods,判斷是不是BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
              • 2.applyBeanPostProcessorsBeforeInitialization執行後置處理器初始化之前的工作,beanProcessor.postProcessBeforeInitialization(result, beanName);
              • 3.invokeInitMethods 調用Bean實例對象初始化的方法,先判斷是否是InitializingBean接口,進行初始化,在判斷是不是自定義初始化方法
              • 4.applyBeanPostProcessorsAfterInitialization執行後置處理器初始化後的工作
            • 5.registerDisposableBeanIfNecessary(beanName, bean, mbd);註冊bean的銷燬方法
        • 9.將創建的bean放到緩衝中

          總結ioc就是這些map

          創建完所有bean後,最後檢查所有的beans是否是SmartInitializingSingleton(@EventListen註解)的,如果是執行afterSingletonsInstantiated

13.finishRefresh()

完成BeanFactory的初始化創建工作,IOC就創建完成了

protected void finishRefresh() {
   // Clear context-level resource caches (such as ASM metadata from scanning).
   clearResourceCaches();

   // 初始化和生命週期有關的後置處理器
   initLifecycleProcessor();

   // 拿到前面定義的生命週期處理器BeanFactory,回調onRefresh()
   getLifecycleProcessor().onRefresh();

   // 發佈容器刷新完成事件
   publishEvent(new ContextRefreshedEvent(this));

   // Participate in LiveBeansView MBean, if active.
   LiveBeansView.registerApplicationContext(this);
}

protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate LifecycleProcessor with name '" +
						LIFECYCLE_PROCESSOR_BEAN_NAME +
						"': using default [" + this.lifecycleProcessor + "]");
			}
		}
	}
  1. initLifecycleProcessor初始化和生命週期有關的後置處理器

    默認從容器中找是否有LifecycleProcessor的組件,如果沒有new DefaultLifecycleProcessor加入到容器

    void onRefresh();
    void onClose();

  2. getLifecycleProcessor().onRefresh(); 拿到前面定義的生命週期處理器BeanFactory,回調onRefresh()

  3. publishEvent(new ContextRefreshedEvent(this));發佈容器刷新完成事件

  4. LiveBeansView.registerApplicationContext(this);

14總結

  1. spring容器在啓動的時候,會保存所有註冊進來的Bean的定義信息
  • xml註冊的bean
  • 註解住的bean
  1. Spring容器會在合適的時機創建這些Bean

    • 用到這個bean的時候,利用getBean創建bean,創建好以後保存在容器中
    • 統一創建所有的bean的時候,finishBeanFactoryInitialization
  2. 後置處理器BeanPosrProcessor

    • 每一個bean創建完成,都會使用各種後置處理器進行處理來增強bean的功能
      AutowiredAnnotationBeanPostProcessor:處理自動注入

      AnnotationAwareAspectJAutoProxyCreator:做aop功能

      還有很多
      增強功能註解
      AsyncAnnotationBeanPostProcessor

  3. 事件驅動模型
    ApplicationListener事件監聽
    ApplicationEventMulticaster 事件派發
    ApplicationEventMulticaster.addApplicationListener(ApplicationListener<?> listener);通過事件派發器加入事件監聽

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章