Spring 容器初始化 register 與 refresh方法
前篇回顧:
Spring源碼解析容器初始化構造方法
在上一篇文章中,我們介紹完瞭AnnotationConfigApplicationContext
的構造方法,本文我們來詳細說說接下來要被調用的方法。
register方法
到上面位為止,AnnotationConfigApplicationContext
構造函數執行完畢,調用register
方法註冊配置類,實際執行方法doRegisterBean
:
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); //判斷這個類是否需要解析,主要根據註解進行判斷 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(instanceSupplier); //得到類的作用域 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); //把類的作用域添加到數據結構中 abd.setScope(scopeMetadata.getScopeName()); //生成類的名字,通過beanNameGenerator String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) { for (Class<? extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
在上面這段代碼中,主要完成這幾項任務:
- 首先根據我們傳入的類創建一個
AnnotatedGenericBeanDefinition
,它可以理解為一個數據結構,其中包含瞭類的一些元信息,例如作用域scope
,懶加載lazy
等屬性。 - 調用
processCommonDefinitionAnnotations
方法,處理類中的通用註解,分析源碼得知處理瞭Lazy
,DependsOn
,Primary
,Role
等註解,處理完成後把它們添加到數據結構中。 - 封裝成
BeanDefinitionHolder
,BeanDefinitionHolder
可以簡單的理解為一個Map
,它關聯BeanDefinition
和beanName
。 - 調用
registerBeanDefinition
方法,將上面的BeanDefinitionHolder
註冊給registry
,這個registry
就是AnnotationConfigApplicationContext
,即BeanDefinitionRegistry
。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { this.beanFactory.registerBeanDefinition(beanName, beanDefinition); }
這裡最終將beanDefinition
註冊給瞭之前實例化的beanFactory
,beanFactory
的實現類為DefaultListableBeanFactory
。
到這,我們已經有兩種方法將一個類轉化為BeanDefinition
:
1、通過RootBeanDefinition
的構造方法
2、調用AnnotatedBeanDefinitionReader
的register
方法
執行完這一步後,可以看到我們的配置類也被放入瞭beanDefinitionMap
,到這裡,spring的工廠初始化工作就完成瞭。
refresh 方法
註冊完成後,調用核心方法refresh
,初始化spring環境:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } ... }
首先可以看到,方法中的代碼是被synchronized
加鎖的,這樣做是為瞭防止一個線程在執行refresh
時,其他線程執行spring容器的啟動或銷毀操作。下面,我們開始分析一下其中重要的方法,重要的註釋會寫在代碼中。
1、prepareRefresh
prepareRefresh
方法中為一些啟動的準備工作,包括記錄啟動時間,是否激活標識位,初始化屬性源配置等工作
protected void prepareRefresh() { // 記錄啟動時間 this.startupDate = System.currentTimeMillis(); // closed 屬性設置為 false this.closed.set(false); //將 active 屬性設置為 true //上面兩個都是 AtomicBoolean類型 this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } //註解模式下此方法為空 initPropertySources(); getEnvironment().validateRequiredProperties(); ... }
2、obtainFreshBeanFactory
返回我們之前創建好的DefaultListableBeanFactory
實例beanFactory
,這裡使用的是它的接口ConfigurableListableBeanFactory
來進行接收。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
這裡進行一下補充,如果是基於xml的配置,那麼是在obtainFreshBeanFactory
方法中初始化BeanFactory
工廠的,並進行bean的加載與註冊,這裡不再贅述。
3、prepareBeanFactory
準備bean工廠,對功能進行填充,例如配置瞭一些標準特征,比如上下文的加載器ClassLoader
和postProcessor
後置處理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); //bean表達式的解釋器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //bean對象與String類型的轉換,例如<property ref="dao"> beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //spring核心代碼,添加一個後置管理器 //能在bean中獲得到各種的*Aware 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); //添加一個用於ApplicationListener的bean從事件廣播器中添加或刪除的後置處理器 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } /* * 如果自定義的bean中沒有名為“systemProperties”和“systemEnvironment”的Bean * 則註冊兩個bean,key為“systemProperties”和“systemEnvironment”,Value為Map * 這兩個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()); } }
需要說明的是添加後置處理器addBeanPostProcessor
方法,在beanFactory
中維護瞭一個spring後置處理器的列表:
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
最終調用的是List的add
方法,將後置處理器添加到列表的尾部:
this.beanPostProcessors.add(beanPostProcessor);
這裡有必要簡單的對BeanPostProcessor
進行一下說明:
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
postProcessBeforeInitialization
在類的初始化之前執行,postProcessAfterInitialization
在類的初始化之後執行。也就是說spring通過暴露出BeanPostProcessor
這個後置處理器,可以讓我們去插手bean的初始化過程。
ApplicationContextAwareProcessor
實現瞭這個接口,通過它spring向外暴露瞭上下文環境ApplicationContext
,供我們調用。
4、postProcessBeanFactory
postProcessBeanFactory
是一個空的方法,沒有任何實現:
/** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for registering special * BeanPostProcessors etc in certain ApplicationContext implementations. * @param beanFactory the bean factory used by the application context */ protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }
看一下源碼中的註釋,可理解可以通過子類擴展當前類,添加一些BeanPostProcessor
,在BeanDefinition
被加載但bean還沒有實例化前,執行這些特殊的後置管理器進行功能擴展。
5、invokeBeanFactoryPostProcessors
在該方法中,執行已被註冊的BeanFactoryPostProcessor
。BeanFactoryPostProcessor
也是spring提供的擴展點之一,它運行於spring容器加載瞭beanDefinition
之後,但還未實例化bean之前執行。通過實現這個接口,可以在bean創建之前修改beanDefinition
的屬性,並且可以同時配置多個BeanFactoryProcessor
,通過設置order
屬性來控制順序。
@FunctionalInterface public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
再來看看invokeBeanFactoryPostProcessors
方法:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
這個需要註意的是getBeanFactoryPostProcessors
方法,這個方法是獲取手動註冊給spring添加的BeanFactoryPostProcessor
,這個“手動註冊”並不是說寫好瞭以後添加一個@Component
註解就可以瞭,因為如果加瞭註解還是spring自己去掃描得到的。
看一下getBeanFactoryPostProcessors
方法,就可以知道是這裡直接返回瞭一個List:
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; }
而通過 AnnotationConfigApplicationContext
的addBeanFactoryPostProcessor
方法進行添加,則直接添加進瞭這個list中:
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) { Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null"); this.beanFactoryPostProcessors.add(postProcessor); }
回到代碼中,調用執行瞭PostProcessorRegistrationDelegate
的invokeBeanFactoryPostProcessors
方法,這個方法用於執行所有註冊的BeanFactoryPostProcessor
。該方法中,創建一個List存放spring內部自己實現瞭BeanDefinitionRegistryPostProcessor
接口的對象,並從beanFactory
中獲取這個type
的bean的名稱:
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
此處,我們可以得到一個對應的beanName
:
在獲取到beanName
後,通過bean工廠的getBean
方法將其實例化,並添加到currentRegistryProcessors
中,然後調用invokeBeanDefinitionRegistryPostProcessors
方法,執行所有的BeanDefinitionRegistryPostProcessor
:
for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); //合並list registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //清除list currentRegistryProcessors.clear();
看一下currentRegistryProcessors
中的實例,這個對象非常重要,會在後面講到:
回到上面的調用過程,我們知道這個Collection
中現在隻有一個對象,所以調用的是上面提到的 ConfigurationClassPostProcessor
對象的 postProcessBeanDefinitionRegistry
方法:
private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
最終調用ConfigurationClassPostProcessor
的processConfigBeanDefinitions
。先看方法的前半段:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { //定義一個list,存放beanFactory中的beanDefinition List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //獲取容器中註冊的所有beanDefinition的名字,目前有瞭7個 String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { //如果BeanDefinition中的configurationClass的屬性為full或者lite,則意味著已經處理過瞭,直接跳過 if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } //判斷是否Configuration類,如果加瞭Configuration下面的這幾個註解就不再判斷瞭 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found if (configCandidates.isEmpty()) { return; }
這裡先讀取瞭BeanFactory
中存放的7個beanDefinition
,然後去判斷是否加瞭以下註解:
@Configuration @ComponentScan @Import @ImportResource
如果是,則添加到configCandidates
的List中,運行到這,可以看到在裡面存瞭一個我們自定義的添加瞭@Configuration
註解的類:
向下運行,首先實例化瞭一個ConfigurationClassParser
,用於解析各個配置類:
ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
然後,實例化 2個Set,candidates
用於將之前加入的configCandidates
進行去重,因為有可能有多個配置類重復瞭。alreadyParsed
用於判斷是否處理過,避免重復。
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
調用ConfigurationClassParser
的parse
方法:
do { parser.parse(candidates); ... } while (!candidates.isEmpty());
parse
方法調用鏈較長,這裡隻列出其調用過程和重要掃描過程:
ConfigurationClassParser # parse(Set<BeanDefinitionHolder> configCandidates) # parse(AnnotationMetadata metadata, String beanName) # processConfigurationClas(ConfigurationClass configClass) # doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
重點看一下doProcessConfigurationClass
方法:
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
得到註解類的註解信息,例如basePackage
等,存放在AnnotationAttributes
中。之後對set
進行遍歷:
for (AnnotationAttributes componentScan : componentScans) { //掃描普通類,會掃描出來所有加瞭@Component註解的類 //並且把掃描出來的普通bean放到map當中 Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); //這一步完成後掃描出來瞭所有類 //檢查掃描出的類是否還有 @Configuration for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { parse(bdCand.getBeanClassName(), holder.getBeanName()); } } }
這裡的關鍵還是parse
方法,調用ComponentScanAnnotationParser
的parse
方法,然後調用ClassPathBeanDefinitionScanner
的doScan
方法,實現掃描核心功能:
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); for (String basePackage : basePackages) { //掃描basePackage路徑下的java文件 //並把它轉成BeanDefinition類型 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { //解析scope屬性 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); //所有掃描出來的類 是 ScannedGenericBeanDefinition ,符合AbstractBeanDefinition //先設置默認值 if (candidate instanceof AbstractBeanDefinition) { //如果這個類是AbstractBeanDefinition的子類 //則為他設置默認值,比如lazy,init ,destroy postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //檢查並且處理常用的註解 //這裡的處理主要是指把常用註解的值設置到AnnotatedBeanDefinition當中 //當前前提是這個類型必須是AnnotatedBeanDefinition類型的,也就是加瞭註解的類 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //加入到BeanDefinitionMap當中 registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
到這,spring已經把所有加瞭@Component
類註解的類掃描出來,並生成對應的beanDefinition
,最後通過registerBeanDefinition
方法,放入beanDefinitionMap
中。
到這,我們執行完瞭ConfigurationClassPostProcessor
的invokeBeanDefinitionRegistryPostProcessors
方法。
回到PostProcessorRegistrationDelegate
的invokeBeanFactoryPostProcessors
方法中繼續向下執行:
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
第二行語句用於執行我們自定義的beanFactoryPostProcessor
,由於現在不存在,可以直接忽略,重點看第一條。
有的同學可能會問,剛才不是執行瞭一條差不多的語句嗎,而且這個registryProcessors
裡面的東西也沒有變,還是ConfigurationClassPostProcessor
,那麼為什麼要執行兩遍?看一下繼承關系:
BeanDefinitionRegistryPostProcessor
對BeanFactoryPostProcessor
進行瞭擴展,添加瞭自己的方法。所以第一次執行的是:
BeanDefinitionRegistryPostProcessor # postProcessBeanDefinitionRegistry
而第二次執行的方法是:
BeanFactoryPostProcessor # postProcessBeanFactory
這裡調用瞭ConfigurationClassPostProcessor
的postProcessBeanFactory
方法:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { int factoryId = System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); }
主要用於給我們的@Configuration
配置類產生cglib
代理,並添加一個ImportAwareBeanPostProcessor
後置處理器,這個後置處理器會在後面實例化bean的過程中用到。
6、registerBeanPostProcessors
這一步用於向spring環境中註冊BeanPostProcessors
後置處理器,前面說過,BeanPostProcessors
的作用是在bean初始化的時候允許我們人工進行插手,當然這裡隻是進行一個註冊的過程,並不會實際執行,具體的執行是bean在初始化的時候。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
調用registerBeanPostProcessors
方法:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
首先從BeanDefinitionMap
中找出所有實現BeanPostProcessor
接口的類,並添加瞭一個BeanPostProcessorChecker
到beanFactory
中,主要用於記錄信息。
然後,創建瞭4個List用於緩存不同類型的後置處理器:
//存放實現PriorityOrdered接口的BeanPostProcessor List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); //存放Spring內部的BeanPostProcesso List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); //存放註冊實現Ordered接口的BeanPostProcessors List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); //存放常規的BeanPostProcessors List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
對4個List分別調用PostProcessorRegistrationDelegate
的registerBeanPostProcessors
方法:
private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); } }
遍歷列表,調用AbstractBeanFactory
的addBeanPostProcessor
方法,將後置處理器加到beanPostProcessors
中:
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); // 如果beanPostProcessor已經存在則移除 this.beanPostProcessors.remove(beanPostProcessor); // beanFactory是否已註冊過InstantiationAwareBeanPostProcessors if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } //beanFactory是否已註冊過DestructionAwareBeanPostProcessor if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } //將beanPostProcessor添加到beanPostProcessors中 this.beanPostProcessors.add(beanPostProcessor); }
在這個方法中,如果beanPostProcessor
已經存在則移除,這樣做可以起到重排序的作用,如果beanPostProcessor
原先在前面,經過刪除後再添加,則變到最後面。到這,將所有實現瞭BeanPostProcessor
接口的類加載到 BeanFactory
中。
7、非重點部分
以下部分是非重點部分,不需要過分關註,因此省略,隻做一個大體的註釋說明:
//初始化上下文的 MessageSource源 initMessageSource(); //初始化應用事件廣播器 initApplicationEventMulticaster(); //空方法,可用做子類擴展 onRefresh(); //在所有註冊的bean中查找Listener bean,註冊到消息廣播器中 registerListeners();
到此這篇關於Spring 容器初始化 register 與 refresh方法的文章就介紹到這瞭,更多相關Spring register 與 refresh方法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Spring的BeanFactoryPostProcessor接口示例代碼詳解
- Spring源碼BeanFactoryPostProcessor詳解
- Spring擴展接口知識總結
- Dubbo3的Spring適配原理與初始化流程源碼解析
- Java 圖解Spring啟動時的後置處理器工作流程是怎樣的