springboot 源碼解析(4)createApplicationContext的創建分析

springboot創建context的解析,我們直接看代碼

Class<?> contextClass = this.applicationContextClass;初始化是空的

下面判斷應用類型。返回不同的類。這裏是SERVLET

case SERVLET:
   contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);

我們看到的類是org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext

我們看BeanUtils.instantiateClass(contextClass)

首先判斷是不是接口clazz.isInterface() java的內部類判斷是不是接口。如果是接口不可以初始化

繼續往下return instantiateClass(clazz.getDeclaredConstructor());

繼續看這個方法我們之前的介紹過了。獲取構造方法判斷構造方法是不是私有的。然後判斷是不是kotlin類型,進行不同的構造

此時創建AnnotationConfigServletWebServerApplicationContext ,我們看下這個類的構造方法

我們知道子類初始化的時候會先調用父類的構造方法會先執行他的父類org.springframework.context.support.GenericApplicationContext#GenericApplicationContext()

嗯。。這裏看到了創建工廠。。。

嗯。。又是super 我們繼續

我們先看supper

我們看

ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);

單例依賴的接口加入進來初始化完畢。我們開始看reader

this.reader = new AnnotatedBeanDefinitionReader(this);

我們看看reader

繼續看getOrCreateEnvironment(registry)

首先判斷registry是不是EnvironmentCapable類型。我們指導registry是AnnotationConfigServletWebServerApplicationContext

我們看下繼承關係

發現他是這個子類。所以繼續走

((EnvironmentCapable) registry).getEnvironment();實際走的是抽象類的org.springframework.context.support.AbstractApplicationContext#getEnvironment

判斷是否爲空 然後走createEnvironment()

創建了一個StandardEnvironment之前有跟過這個類了。我們就不跟了。就是創建了一個標準的環境,裏面有一些默認的參數

我們返回去繼續看

我們看this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);這個

現在看到一個關鍵的東西beanFactory  我們繼續往下看

this.beanFactory = deduceBeanFactory(registry);

這裏判斷了是什麼類型的我們看看他到底是什麼類型的

發現他是

ConfigurableApplicationContext所以執行的
(((ConfigurableApplicationContext) source).getBeanFactory());然後返回了getBeanFactory返回上面創建的默認工廠

我們繼續看這個

this.environment = (environment != null ? environment : deduceEnvironment(registry));

這個環境之前已經有了。直接賦值

我們往下看

this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));

尋找resource的加載器,我們看他如何實現的

依然是判斷這個類是不是ResourceLoader 剛纔我們看繼承關係看到了他是屬於的。所以返回了source,不信你看

this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);設置加載器

好了。我們繼續看之前的代碼

我們看看這個註冊

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);是什麼

繼續跟進去

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

獲取剛纔的bean工廠。如果不存在就獲取默認的工廠這個方法我截圖出來了

然後往下看

!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator) 如果不是這個類型的

設置爲DependencyComparator爲AnnotationAwareOrderComparator(OrderComparator的子類,用來支持Spring的Ordered類、@Order註解和@Priority註解。)

我們繼續往下看

if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
   beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}

一樣的判斷一樣的設置 setAutowireCandidateResolver Spring依賴注入核心接口@Autowired@Primary@Qualifier@Value@Lazy等註解的處理,後面會寫到。先知道他是幹啥的

 

下一章我們分析他如何註冊bean

 

 

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