Spring?容器初始化?register?與?refresh方法
前篇回顧:
在上一篇文章中,我們介紹完了AnnotationConfigApplicationContext的構(gòu)造方法,本文我們來詳細(xì)說說接下來要被調(diào)用的方法。
register方法
到上面位為止,AnnotationConfigApplicationContext構(gòu)造函數(shù)執(zhí)行完畢,調(diào)用register方法注冊配置類,實(shí)際執(zhí)行方法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);
//判斷這個類是否需要解析,主要根據(jù)注解進(jìn)行判斷
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//得到類的作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//把類的作用域添加到數(shù)據(jù)結(jié)構(gòu)中
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);
}在上面這段代碼中,主要完成這幾項(xiàng)任務(wù):
- 首先根據(jù)我們傳入的類創(chuàng)建一個
AnnotatedGenericBeanDefinition,它可以理解為一個數(shù)據(jù)結(jié)構(gòu),其中包含了類的一些元信息,例如作用域scope,懶加載lazy等屬性。 - 調(diào)用
processCommonDefinitionAnnotations方法,處理類中的通用注解,分析源碼得知處理了Lazy,DependsOn,Primary,Role等注解,處理完成后把它們添加到數(shù)據(jù)結(jié)構(gòu)中。 - 封裝成
BeanDefinitionHolder,BeanDefinitionHolder可以簡單的理解為一個Map,它關(guān)聯(lián)BeanDefinition和beanName。 - 調(diào)用
registerBeanDefinition方法,將上面的BeanDefinitionHolder注冊給registry,這個registry就是AnnotationConfigApplicationContext,即BeanDefinitionRegistry。
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}這里最終將beanDefinition注冊給了之前實(shí)例化的beanFactory,beanFactory的實(shí)現(xiàn)類為DefaultListableBeanFactory。
到這,我們已經(jīng)有兩種方法將一個類轉(zhuǎn)化為BeanDefinition:
1、通過RootBeanDefinition 的構(gòu)造方法
2、調(diào)用AnnotatedBeanDefinitionReader的register方法
執(zhí)行完這一步后,可以看到我們的配置類也被放入了beanDefinitionMap,到這里,spring的工廠初始化工作就完成了。

refresh 方法
注冊完成后,調(diào)用核心方法refresh,初始化spring環(huán)境:
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加鎖的,這樣做是為了防止一個線程在執(zhí)行refresh時,其他線程執(zhí)行spring容器的啟動或銷毀操作。下面,我們開始分析一下其中重要的方法,重要的注釋會寫在代碼中。
1、prepareRefresh
prepareRefresh方法中為一些啟動的準(zhǔn)備工作,包括記錄啟動時間,是否激活標(biāo)識位,初始化屬性源配置等工作
protected void prepareRefresh() {
// 記錄啟動時間
this.startupDate = System.currentTimeMillis();
// closed 屬性設(shè)置為 false
this.closed.set(false);
//將 active 屬性設(shè)置為 true
//上面兩個都是 AtomicBoolean類型
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
//注解模式下此方法為空
initPropertySources();
getEnvironment().validateRequiredProperties();
...
}2、obtainFreshBeanFactory
返回我們之前創(chuàng)建好的DefaultListableBeanFactory實(shí)例beanFactory,這里使用的是它的接口ConfigurableListableBeanFactory來進(jìn)行接收。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}這里進(jìn)行一下補(bǔ)充,如果是基于xml的配置,那么是在obtainFreshBeanFactory方法中初始化BeanFactory工廠的,并進(jìn)行bean的加載與注冊,這里不再贅述。
3、prepareBeanFactory
準(zhǔn)備bean工廠,對功能進(jìn)行填充,例如配置了一些標(biāo)準(zhǔn)特征,比如上下文的加載器ClassLoader和postProcessor后置處理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.setBeanClassLoader(getClassLoader());
//bean表達(dá)式的解釋器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//bean對象與String類型的轉(zhuǎn)換,例如<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就是一些系統(tǒng)配置和系統(tǒng)環(huán)境信息
* */
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中維護(hù)了一個spring后置處理器的列表:
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
最終調(diào)用的是List的add方法,將后置處理器添加到列表的尾部:
this.beanPostProcessors.add(beanPostProcessor);
這里有必要簡單的對BeanPostProcessor進(jìn)行一下說明:
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在類的初始化之前執(zhí)行,postProcessAfterInitialization在類的初始化之后執(zhí)行。也就是說spring通過暴露出BeanPostProcessor這個后置處理器,可以讓我們?nèi)ゲ迨謆ean的初始化過程。
ApplicationContextAwareProcessor實(shí)現(xiàn)了這個接口,通過它spring向外暴露了上下文環(huán)境ApplicationContext,供我們調(diào)用。
4、postProcessBeanFactory
postProcessBeanFactory是一個空的方法,沒有任何實(shí)現(xiàn):
/**
* 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) {
}看一下源碼中的注釋,可理解可以通過子類擴(kuò)展當(dāng)前類,添加一些BeanPostProcessor,在BeanDefinition被加載但bean還沒有實(shí)例化前,執(zhí)行這些特殊的后置管理器進(jìn)行功能擴(kuò)展。
5、invokeBeanFactoryPostProcessors
在該方法中,執(zhí)行已被注冊的BeanFactoryPostProcessor。BeanFactoryPostProcessor也是spring提供的擴(kuò)展點(diǎn)之一,它運(yùn)行于spring容器加載了beanDefinition之后,但還未實(shí)例化bean之前執(zhí)行。通過實(shí)現(xiàn)這個接口,可以在bean創(chuàng)建之前修改beanDefinition的屬性,并且可以同時配置多個BeanFactoryProcessor,通過設(shè)置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注解就可以了,因?yàn)槿绻恿俗⒔膺€是spring自己去掃描得到的。
看一下getBeanFactoryPostProcessors方法,就可以知道是這里直接返回了一個List:
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}而通過 AnnotationConfigApplicationContext的addBeanFactoryPostProcessor方法進(jìn)行添加,則直接添加進(jìn)了這個list中:
public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null");
this.beanFactoryPostProcessors.add(postProcessor);
}回到代碼中,調(diào)用執(zhí)行了PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors 方法,這個方法用于執(zhí)行所有注冊的BeanFactoryPostProcessor。該方法中,創(chuàng)建一個List存放spring內(nèi)部自己實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口的對象,并從beanFactory中獲取這個type的bean的名稱:
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);此處,我們可以得到一個對應(yīng)的beanName:

在獲取到beanName后,通過bean工廠的getBean方法將其實(shí)例化,并添加到currentRegistryProcessors中,然后調(diào)用invokeBeanDefinitionRegistryPostProcessors方法,執(zhí)行所有的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中的實(shí)例,這個對象非常重要,會在后面講到:

回到上面的調(diào)用過程,我們知道這個Collection中現(xiàn)在只有一個對象,所以調(diào)用的是上面提到的 ConfigurationClassPostProcessor對象的 postProcessBeanDefinitionRegistry方法:
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}最終調(diào)用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,則意味著已經(jīng)處理過了,直接跳過
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中,運(yùn)行到這,可以看到在里面存了一個我們自定義的添加了@Configuration注解的類:

向下運(yùn)行,首先實(shí)例化了一個ConfigurationClassParser,用于解析各個配置類:
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);然后,實(shí)例化 2個Set,candidates 用于將之前加入的configCandidates進(jìn)行去重,因?yàn)橛锌赡苡卸鄠€配置類重復(fù)了。alreadyParsed 用于判斷是否處理過,避免重復(fù)。
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
調(diào)用ConfigurationClassParser的parse方法:
do {
parser.parse(candidates);
...
}
while (!candidates.isEmpty());parse方法調(diào)用鏈較長,這里只列出其調(diào)用過程和重要掃描過程:
ConfigurationClassParser # parse(Set<BeanDefinitionHolder> configCandidates) # parse(AnnotationMetadata metadata, String beanName) # processConfigurationClas(ConfigurationClass configClass) # doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
重點(diǎn)看一下doProcessConfigurationClass方法:
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);得到注解類的注解信息,例如basePackage等,存放在AnnotationAttributes中。之后對set進(jìn)行遍歷:
for (AnnotationAttributes componentScan : componentScans) {
//掃描普通類,會掃描出來所有加了@Component注解的類
//并且把掃描出來的普通bean放到map當(dāng)中
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());
}
}
}這里的關(guān)鍵還是parse方法,調(diào)用ComponentScanAnnotationParser 的parse方法,然后調(diào)用ClassPathBeanDefinitionScanner的doScan方法,實(shí)現(xiàn)掃描核心功能:
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文件
//并把它轉(zhuǎn)成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
//先設(shè)置默認(rèn)值
if (candidate instanceof AbstractBeanDefinition) {
//如果這個類是AbstractBeanDefinition的子類
//則為他設(shè)置默認(rèn)值,比如lazy,init ,destroy
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//檢查并且處理常用的注解
//這里的處理主要是指把常用注解的值設(shè)置到AnnotatedBeanDefinition當(dāng)中
//當(dāng)前前提是這個類型必須是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當(dāng)中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
到這,spring已經(jīng)把所有加了@Component類注解的類掃描出來,并生成對應(yīng)的beanDefinition,最后通過registerBeanDefinition方法,放入beanDefinitionMap中。
到這,我們執(zhí)行完了ConfigurationClassPostProcessor的invokeBeanDefinitionRegistryPostProcessors方法。
回到PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法中繼續(xù)向下執(zhí)行:
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
第二行語句用于執(zhí)行我們自定義的beanFactoryPostProcessor,由于現(xiàn)在不存在,可以直接忽略,重點(diǎn)看第一條。
有的同學(xué)可能會問,剛才不是執(zhí)行了一條差不多的語句嗎,而且這個registryProcessors里面的東西也沒有變,還是ConfigurationClassPostProcessor,那么為什么要執(zhí)行兩遍?看一下繼承關(guān)系:

BeanDefinitionRegistryPostProcessor對BeanFactoryPostProcessor進(jìn)行了擴(kuò)展,添加了自己的方法。所以第一次執(zhí)行的是:
BeanDefinitionRegistryPostProcessor # postProcessBeanDefinitionRegistry
而第二次執(zhí)行的方法是:
BeanFactoryPostProcessor # postProcessBeanFactory
這里調(diào)用了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配置類產(chǎn)生cglib代理,并添加一個ImportAwareBeanPostProcessor后置處理器,這個后置處理器會在后面實(shí)例化bean的過程中用到。
6、registerBeanPostProcessors
這一步用于向spring環(huán)境中注冊BeanPostProcessors后置處理器,前面說過,BeanPostProcessors的作用是在bean初始化的時候允許我們?nèi)斯みM(jìn)行插手,當(dāng)然這里只是進(jìn)行一個注冊的過程,并不會實(shí)際執(zhí)行,具體的執(zhí)行是bean在初始化的時候。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}調(diào)用registerBeanPostProcessors方法:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
首先從BeanDefinitionMap中找出所有實(shí)現(xiàn)BeanPostProcessor接口的類,并添加了一個BeanPostProcessorChecker到beanFactory中,主要用于記錄信息。
然后,創(chuàng)建了4個List用于緩存不同類型的后置處理器:
//存放實(shí)現(xiàn)PriorityOrdered接口的BeanPostProcessor List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); //存放Spring內(nèi)部的BeanPostProcesso List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); //存放注冊實(shí)現(xiàn)Ordered接口的BeanPostProcessors List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); //存放常規(guī)的BeanPostProcessors List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
對4個List分別調(diào)用PostProcessorRegistrationDelegate的registerBeanPostProcessors方法:
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}遍歷列表,調(diào)用AbstractBeanFactory的addBeanPostProcessor方法,將后置處理器加到beanPostProcessors中:
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// 如果beanPostProcessor已經(jīng)存在則移除
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已經(jīng)存在則移除,這樣做可以起到重排序的作用,如果beanPostProcessor原先在前面,經(jīng)過刪除后再添加,則變到最后面。到這,將所有實(shí)現(xiàn)了BeanPostProcessor接口的類加載到 BeanFactory 中。
7、非重點(diǎn)部分
以下部分是非重點(diǎn)部分,不需要過分關(guān)注,因此省略,只做一個大體的注釋說明:
//初始化上下文的 MessageSource源 initMessageSource(); //初始化應(yīng)用事件廣播器 initApplicationEventMulticaster(); //空方法,可用做子類擴(kuò)展 onRefresh(); //在所有注冊的bean中查找Listener bean,注冊到消息廣播器中 registerListeners();
到此這篇關(guān)于Spring 容器初始化 register 與 refresh方法的文章就介紹到這了,更多相關(guān)Spring register 與 refresh方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IDEA 2021配置JavaWeb項(xiàng)目超詳細(xì)教程
本文通過圖文并茂的形式給大家介紹IDEA 2021配置JavaWeb項(xiàng)目的過程,內(nèi)容簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-08-08
MyBatis利用攔截器實(shí)現(xiàn)數(shù)據(jù)脫敏詳解
現(xiàn)代網(wǎng)絡(luò)環(huán)境中,敏感數(shù)據(jù)的處理是至關(guān)重要的,敏感數(shù)據(jù)包括個人身份信息、銀行賬號、手機(jī)號碼等,所以本文主要為大家詳細(xì)介紹了MyBatis如何利用攔截器實(shí)現(xiàn)數(shù)據(jù)脫敏,希望對大家有所幫助2023-11-11
Spring Boot實(shí)現(xiàn)通用的接口參數(shù)校驗(yàn)
本文介紹基于 Spring Boot 和 JDK8 編寫一個 AOP ,結(jié)合自定義注解實(shí)現(xiàn)通用的接口參數(shù)校驗(yàn)。具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Spring Cloud重試機(jī)制與各組件的重試總結(jié)
這篇文章主要給大家介紹了關(guān)于Spring Cloud中重試機(jī)制與各組件的重試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11
Java數(shù)據(jù)結(jié)構(gòu)及算法實(shí)例:考拉茲猜想 Collatz Conjecture
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)及算法實(shí)例:考拉茲猜想 Collatz Conjecture,本文直接給出實(shí)現(xiàn)代碼,代碼中包含詳細(xì)注釋,需要的朋友可以參考下2015-06-06

