詳解Spring ApplicationContext加載過程
1、找準(zhǔn)入口,使用ClassPathXmlApplicationContext的構(gòu)造方法加載配置文件,用于加載classPath下的配置文件
//第一行,執(zhí)行完成之后就完成了spring配置文件的加載,刷新spring上下文
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(
"classpath:spring-mvc.xml");
//獲取實(shí)例Bean
Person person=context.getBean("person",Person.class);
2、ClassPathXmlApplicationContext構(gòu)造方法源碼如下:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
//設(shè)置父級的ApplicationContext,null
super(parent);
//1.設(shè)置配置文件的路徑, 2. 將路徑中的占位符${placeholder}使用系統(tǒng)的變量替換
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
3、主要方法為setConfigLocation(configLocation),這個方法調(diào)用其父類AbstractRefreshableConfigApplicationContext中的方法
//locations : 配置文件路徑
public void setConfigLocations(String[] locations) {
if (locations != null) {
//斷言
Assert.noNullElements(locations, "Config locations must not be null");
//存儲配置文件路徑的數(shù)組,存儲去掉占位符后的文件路徑數(shù)組
this.configLocations = new String[locations.length];
//遍歷locations,解析占位符
for (int i = 0; i < locations.length; i++) {
//調(diào)用resolvePath解析占位符
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}
4、進(jìn)入resovePath的源碼,實(shí)際上執(zhí)行的是AbstractPropertyResolver的doResolverPlaceholders方法
/**
* text : 需要解析的路徑
* PropertyPlaceholderHelper : 這個是解析系統(tǒng)占位符的輔助類,主要用來將占位符替換成系統(tǒng)的環(huán)境變量
*/
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
//調(diào)用PropertyPlaceholderHelper類中的replacePlaceholders方法
return helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {
public String resolvePlaceholder(String placeholderName) {
return getPropertyAsRawString(placeholderName);
}
});
}
5、進(jìn)入PropertyHelper的replacePlaceholder方法,實(shí)際上調(diào)用PropertyPlaceholderHelper的parseStringValue解析占位符
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
Assert.notNull(value, "Argument 'value' must not be null.");
//調(diào)用的是parseStringValue方法
return parseStringValue(value, placeholderResolver, new HashSet<String>());
}
/**
* strVal : 需要解析的字符串,就是配置文件的路徑
* placeholderResolver : 策略接口,占位符解析器
* visitedPlaceholders : 存儲已經(jīng)訪問過的占位符
**/
protected String parseStringValue(
String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {
//將strval轉(zhuǎn)換成StringBuilder,便于后續(xù)到操作
StringBuilder buf = new StringBuilder(strVal);
//this.placeholderPrefix這個是占位符的前綴 ${,在創(chuàng)建PropertyHelper的時候就已經(jīng)指定了占位符的placeholderPrefix="${" ,placeholderSuffix="}",valueSeparator=":"
//獲取前綴在這個配置文件路徑中的開始索引
int startIndex = strVal.indexOf(this.placeholderPrefix);
while (startIndex != -1) {
//占位符前綴在路徑中的結(jié)束索引
int endIndex = findPlaceholderEndIndex(buf, startIndex);
//如果結(jié)束索引存在
if (endIndex != -1) {
//此時取出${plcaeholder}中的占位符內(nèi)容placeholder
String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
//保存取出來的占位符內(nèi)容placeholder
String originalPlaceholder = placeholder;
//如果占位符中的內(nèi)容已經(jīng)被訪問過了,拋出出異常返回,遞歸結(jié)束的條件
if (!visitedPlaceholders.add(originalPlaceholder)) {
throw new IllegalArgumentException(
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
}
//遞歸解析已經(jīng)取出的占位符中的內(nèi)容 palceholder
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
//這個最重要的一步,將解析占位符內(nèi)容placeholder的值,比如將java.version轉(zhuǎn)換成1.8.0_60
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
if (propVal == null && this.valueSeparator != null) {
int separatorIndex = placeholder.indexOf(this.valueSeparator);
if (separatorIndex != -1) {
String actualPlaceholder = placeholder.substring(0, separatorIndex);
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
if (propVal == null) {
propVal = defaultValue;
}
}
}
//如果解析出來的占位符不為空,比如${java.version}將被解析成 1.8.0_60
if (propVal != null) {
//此時繼續(xù)遞歸解析出1.8.0_60中的占位符
propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
//將路徑中的占位符替換成系統(tǒng)變量的值,比如將${java.version} 替換成 1.8.0_60
buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
if (logger.isTraceEnabled()) {
logger.trace("Resolved placeholder '" + placeholder + "'");
}
//繼續(xù)在路徑字符串中剩余的子串中查找占位符,如果有占位符,那么還會繼續(xù)解析占位符
startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
}
else if (this.ignoreUnresolvablePlaceholders) {
// Proceed with unprocessed value.
startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
else {
throw new IllegalArgumentException("Could not resolve placeholder '" +
placeholder + "'" + " in string value \"" + strVal + "\"");
}
//將已轉(zhuǎn)換成功的占位符從以訪問的集合中移除即可
visitedPlaceholders.remove(originalPlaceholder);
}
else {
startIndex = -1;
}
}
return buf.toString(); //將解析完成之后的配置文件返回
}
6、然后是ClassPathXmlApplicationContext中的refresh方法,實(shí)際上調(diào)用的是父類AbstractApplicationContext的方法
//刷新spring上下文
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//在刷新之前設(shè)置一些參數(shù),比如設(shè)置開始時間戳,上下文是否激活的標(biāo)志,輸出刷新上下文的信息,驗(yàn)證一些必要的屬性
prepareRefresh();
//需要創(chuàng)建beanFactory,如果已經(jīng)存在beanFactory,那么關(guān)閉,詳細(xì)其請看 10
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 準(zhǔn)備上下文工廠,詳情見12
prepareBeanFactory(beanFactory);
try {
//允許子類向后置處理器添加組件
postProcessBeanFactory(beanFactory);
// 調(diào)用BeanFactoryPostProcessor和BeanDefintionRegistoryPostProcessor這兩個后置處理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊BeanPostProcessor,用來攔截bean的創(chuàng)建,詳情見 14
registerBeanPostProcessors(beanFactory);
//初始化消息源
initMessageSource();
// 初始化應(yīng)用程序事件廣播器,用戶可以自定義一個事件廣播器,如果用戶沒有定義,那么使用默認(rèn)的事件廣播器SimpleApplicationEventMulticaster
initApplicationEventMulticaster();
// 在其他子類中初始化bean
onRefresh();
// 檢測事件監(jiān)聽器
registerListeners();
//完成實(shí)例化剩余的單例(non-lazy-init)
finishBeanFactoryInitialization(beanFactory);
// 完成刷新,初始化生命周期處理器......
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
7、進(jìn)入obtainFreshBeanFactory方法
//AbastractApplicationContext的方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//實(shí)際刷新上下文的方法,這個方法就是實(shí)際的刷新上下文方法,其中會調(diào)用loadBeanDefinitions(beanFactory);加載配置文件中的內(nèi)容到BeanDefiniton中
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
//org.springframework.context.support.AbstractRefreshableApplicationContext中的方法
//AbstractApplicationContext的子類中的方法
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果其中有beanfactory,那么銷毀
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//重新創(chuàng)建一個beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//設(shè)置序列化id
beanFactory.setSerializationId(getId());
//定制beanFactory,設(shè)置相關(guān)屬性,包括是否允許覆蓋名稱的不同定義的對象及循環(huán)依賴以及
//設(shè)置@Autowired和@Qualifier,注解解析器QualifierAnnotationAutowireCandidateResolver
customizeBeanFactory(beanFactory);
//加載BeanDefine 詳情見 11
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
8、進(jìn)入loadBeanDefinitions(beanFactory)方法
//這個是org.springframework.context.support.AbstractXmlApplicationContext類中的方法
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//創(chuàng)建要給beanDefinitionReader,用于讀取BeanDefinition
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//配置XmlBeanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
//加載BeanDefiniton,主要的功能從配置文件中讀取BeanDefiniton注冊到注冊表中
loadBeanDefinitions(beanDefinitionReader);
}
9、prepareBeanFactory:準(zhǔn)備BeanFactory
//準(zhǔn)備BeanFactory,設(shè)置一些參數(shù),比如后置處理器,
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//設(shè)置類加載器
beanFactory.setBeanClassLoader(getClassLoader());
//設(shè)置表達(dá)式解析器,用來解析BeanDefiniton中的帶有表達(dá)式的值
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 配置后置處理器,主要的作用就是在spring實(shí)例化bean的前后做一些操作
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略自動裝配的類,這些類都不能使用@Resource或者@Autowired自動裝配獲取對象
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);
//在添加一個應(yīng)用程序監(jiān)聽器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//檢查這些類是否被
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 將下面這些類注冊到容器中,使用registerSingleton方法注冊,我們可以直接從容器中獲取這些類的對象使用
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());
}
}
10、調(diào)用BeanFactory的后置處理器,主要的功能就是調(diào)用注冊在容器中的BeanFactoryPostProcessor和BeanDefinitionRegistoryPostProcessor
//實(shí)例化和調(diào)用BeanFactory后置處理器,必須在單例實(shí)例化之前調(diào)用
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//調(diào)用后置處理器注冊委托類的方法調(diào)用,getBeanFactoryPostProcessors用于獲取注冊的全部的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
//實(shí)際的調(diào)用方法,PostProcessorRegistrationDelegate中的方法
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
//如果beanFactory是BeanDefinitionRegistry的子類,BeanDefinitionRegistry使用來向注冊表中注冊Bean的元信息的(BeanDefintion)
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//存放BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
//存放BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
new LinkedList<BeanDefinitionRegistryPostProcessor>();
//遍歷。判斷是否是BeanDefinitionRegistryPostProcessor實(shí)例
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryPostProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//調(diào)用BeanDefinitionRegistryPostProcessor
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
//添加
registryPostProcessors.add(registryPostProcessor);
}
else {
//表示這個是BeanFactoryPostProcessor實(shí)例,添加進(jìn)集合
regularPostProcessors.add(postProcessor);
}
}
//--- 根據(jù)類型類型獲取beanFactory中注冊的BeanDefinitionRegistryPostProcessor的bean的所有名稱數(shù)組
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// ---- 首先調(diào)用的是BeanDefinitionRegistryPostProcessor類型的后置處理器
//存放實(shí)現(xiàn)PriorityOrdered這個接口的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
//遍歷,如果實(shí)現(xiàn)了PriorityOrdered這個接口就保存下來
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//按照優(yōu)先級排序
OrderComparator.sort(priorityOrderedPostProcessors);
//添加進(jìn)入集合
registryPostProcessors.addAll(priorityOrderedPostProcessors);
//首先調(diào)用實(shí)現(xiàn)PriorityOrdered這個接口的BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
// ---- 下面是調(diào)用實(shí)現(xiàn)Orderd這個接口的BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
OrderComparator.sort(orderedPostProcessors);
registryPostProcessors.addAll(orderedPostProcessors);
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
// ---- 最終調(diào)用剩余全部的BeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
registryPostProcessors.add(pp);
processedBeans.add(ppName);
pp.postProcessBeanDefinitionRegistry(registry);
reiterate = true;
}
}
}
// 調(diào)用BeanFactoryPostProcessor接口中的方法,因?yàn)锽eanDefitionRegistory繼承了這個接口
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//--- 下面是調(diào)用實(shí)現(xiàn)BeanFactoryPostProcessor接口的類,和上面的流程一樣
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
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.
OrderComparator.sort(priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
OrderComparator.sort(orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}
11、注冊BeanPostProcessor,用來攔截Bean的創(chuàng)建,這個接口可以實(shí)現(xiàn)在Bean初始化和初始化之后執(zhí)行相關(guān)的操作
//依然這里依然調(diào)用的PostProcessorRegistrationDelegate,其中包含了注冊后置處理器和調(diào)用后置處理器的方法,相當(dāng)于一個代理人
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
//PostProcessorRegistrationDelegate中的注冊BeanPostProcessors的方法
//其中beanFactory這個新創(chuàng)建的beanFactory,其中的BeanPostProcessor都沒有注冊,applicationContext這個是之前創(chuàng)建的,其中的處理器已經(jīng)注冊過了
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//根據(jù)類型新加載全部的BeanFactoryProcessor的類,
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//創(chuàng)建BeanPostProcessor檢測器
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<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
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.
OrderComparator.sort(priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
OrderComparator.sort(orderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
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.
OrderComparator.sort(internalPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
以上就是詳解Spring ApplicationContext加載過程的詳細(xì)內(nèi)容,更多關(guān)于Spring ApplicationContext加載過程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring+Quartz實(shí)現(xiàn)動態(tài)任務(wù)調(diào)度詳解
這篇文章主要介紹了Spring+Quartz實(shí)現(xiàn)動態(tài)任務(wù)調(diào)度詳解,最近經(jīng)常基于spring?boot寫定時任務(wù),并且是使用注解的方式進(jìn)行實(shí)現(xiàn),分成的方便將自己的類注入spring容器,需要的朋友可以參考下2024-01-01
Java Semaphore實(shí)現(xiàn)高并發(fā)場景下的流量控制
在java開發(fā)的工作中是否會出現(xiàn)這樣的場景,你需要實(shí)現(xiàn)一些異步運(yùn)行的任務(wù),該任務(wù)可能存在消耗大量內(nèi)存的情況,所以需要對任務(wù)進(jìn)行并發(fā)控制。本文將介紹通過Semaphore類優(yōu)雅的實(shí)現(xiàn)并發(fā)控制,感興趣的可以了解一下2021-12-12
Java集合操作之List接口及其實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java集合操作之List接口及其實(shí)現(xiàn)方法,詳細(xì)分析了Java集合操作中List接口原理、功能、用法及操作注意事項(xiàng),需要的朋友可以參考下2015-07-07
SpringBoot 鉤子接口的實(shí)現(xiàn)代碼
本文主要介紹了SpringBoot 鉤子接口,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
Java8之函數(shù)式接口及常用函數(shù)式接口講解
這篇文章主要介紹了Java8之函數(shù)式接口及常用函數(shù)式接口,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11
使用Java的Lucene搜索工具對檢索結(jié)果進(jìn)行分組和分頁
這篇文章主要介紹了使用Java的搜索工具Lucene對檢索結(jié)果進(jìn)行分組和分頁的方法,Luence是Java環(huán)境中的一個全文檢索引擎工具包,需要的朋友可以參考下2016-03-03
解決springboot服務(wù)啟動報(bào)錯:Unable?to?start?embedded?contain
這篇文章主要介紹了解決springboot服務(wù)啟動報(bào)錯:Unable?to?start?embedded?contain的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

