SpringBoot 創(chuàng)建容器的實(shí)現(xiàn)
spring 容器的創(chuàng)建對(duì)應(yīng) SpringApplication 中 run 中調(diào)用的 createApplicationContext 方法。這里創(chuàng)建了一個(gè) web 容器,接下就進(jìn)去 prepareContext 容器準(zhǔn)備階段:
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
//為容器設(shè)置環(huán)境
context.setEnvironment(environment);
//這里的空實(shí)現(xiàn)留給開發(fā)者擴(kuò)展,設(shè)置數(shù)據(jù)轉(zhuǎn)換的ConversionService
postProcessApplicationContext(context);
//執(zhí)行容器中的 Initializers 的 initialize 方法
applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
listeners.contextLoaded(context);
}
看一下這里的 load 方法,這里主要把我們的啟動(dòng)類作為 Bean 注冊(cè)到了 Spring 的容器中。
protected void load(ApplicationContext context, Object[] sources) {
if (logger.isDebugEnabled()) {
logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
}
BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
if (this.beanNameGenerator != null) {
loader.setBeanNameGenerator(this.beanNameGenerator);
}
if (this.resourceLoader != null) {
loader.setResourceLoader(this.resourceLoader);
}
if (this.environment != null) {
loader.setEnvironment(this.environment);
}
loader.load();
}
/**
* Load the sources into the reader.
* @return the number of loaded beans
*/
int load() {
int count = 0;
for (Object source : this.sources) {
count += load(source);
}
return count;
}
private int load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class<?>) {
return load((Class<?>) source);
}
if (source instanceof Resource) {
return load((Resource) source);
}
if (source instanceof Package) {
return load((Package) source);
}
if (source instanceof CharSequence) {
return load((CharSequence) source);
}
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}
private int load(Class<?> source) {
if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
// Any GroovyLoaders added in beans{} DSL can contribute beans here
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
load(loader);
}
if (isEligible(source)) {
this.annotatedReader.register(source);
return 1;
}
return 0;
}
再來(lái)看下 contextLoaded 方法,這里將上下文設(shè)置到監(jiān)聽器中,同時(shí)也把監(jiān)聽器添加到上下文中。最后發(fā)布了一個(gè) ApplicationPreparedEvent 事件。
public void contextLoaded(ConfigurableApplicationContext context) {
for (ApplicationListener<?> listener : this.application.getListeners()) {
if (listener instanceof ApplicationContextAware) {
((ApplicationContextAware) listener).setApplicationContext(context);
}
context.addApplicationListener(listener);
}
this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}
到此這篇關(guān)于SpringBoot 創(chuàng)建容器的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot 創(chuàng)建容器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳談spring boot中幾種常見的依賴注入問(wèn)題
這篇文章主要介紹了spring boot中幾種常見的依賴注入問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringBoot優(yōu)雅地實(shí)現(xiàn)全局異常處理的方法詳解
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何優(yōu)雅地實(shí)現(xiàn)全局異常處理,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-08-08
springboot構(gòu)建docker鏡像并推送到阿里云
本文主要介紹了springboot構(gòu)建docker鏡像并推送到阿里云,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
@Scheduled定時(shí)器使用注意事項(xiàng)及說(shuō)明
這篇文章主要介紹了@Scheduled定時(shí)器使用注意事項(xiàng)及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
SpringBoot使用maven實(shí)現(xiàn)多環(huán)境運(yùn)行和打包的操作步驟
在開發(fā)過(guò)程中,需要不斷進(jìn)行環(huán)境的切換和打包部署,maven提供了多環(huán)境配置,可以方便實(shí)現(xiàn)不同環(huán)境的配置切換和打包,本文通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04

