-
前言
上文已經(jīng)介紹了配置資源和環(huán)境初始化的過程蠢正。本節(jié)只講解createApplicationContext上下文應(yīng)用創(chuàng)建铲咨。
文章基于springboot2.3.x系列的源碼(大部分以jar包中的源碼為例講解)溜徙,github的源碼與實(shí)際發(fā)版的可能略微不同琅关,不過整體流程差別不大舅世。
本人第一次寫文章凄硼,如有錯(cuò)誤或誤導(dǎo)歡迎留言指正。文章整體可能比較啰嗦匠楚,盡可能的將流程中的每一個(gè)重要的方法都講到巍膘。 -
createApplicationContext 創(chuàng)建上下文應(yīng)用
源碼:
protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch(this.webApplicationType) { case SERVLET: contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext"); break; case REACTIVE: contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext"); break; default: contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext"); } } catch (ClassNotFoundException var3) { throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3); } } return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass); }
webApplicationType默認(rèn)值為SERVLET,這里對(duì)應(yīng)會(huì)獲取AnnotationConfigServletWebServerApplicationContext的class對(duì)象油啤。通過BeanUtils.instantiateClass實(shí)例化對(duì)象典徘,其實(shí)直接通過new創(chuàng)建出來效果一樣蟀苛,并且在以后版本的源碼中是直接使用new創(chuàng)建的益咬。這個(gè)類的作用通過名稱也可以知道,是基于注解形式的web上下文應(yīng)用構(gòu)建帜平。與之相對(duì)應(yīng)的是xml方式XmlServletWebServerApplicationContext幽告。
先看一下這個(gè)關(guān)鍵類的uml圖:
這里圖片上的字比較小,如果看不清也可以通過自己的idea去查看裆甩。關(guān)系比較復(fù)雜冗锁,但是可以在圖上看到幾個(gè)常見的類。BeanFactory嗤栓、ResourceLoader冻河、lifecycle等≤运В可以看出頂層的都是接口叨叙,下面的實(shí)現(xiàn)類也相互交叉,其公共的父類之一是ApplicationContext接口堪澎。
-
AnnotationConfigServletWebServerApplicationContext 初始化
這里開始我們需要去了解AnnotationConfigServletWebServerApplicationContext的自身和其父類擂错,因?yàn)榈竭@里開始,有很多初始化動(dòng)作已經(jīng)在構(gòu)造函數(shù)內(nèi)進(jìn)行了樱蛤。
從自身開始:
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry { private final AnnotatedBeanDefinitionReader reader; private final ClassPathBeanDefinitionScanner scanner; private final Set<Class<?>> annotatedClasses; private String[] basePackages; public AnnotationConfigServletWebServerApplicationContext() { this.annotatedClasses = new LinkedHashSet(); this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); } ...... //還有其他的構(gòu)造函數(shù)钮呀,這里我們只選啟動(dòng)流程默認(rèn)的無參構(gòu)造函數(shù) }
構(gòu)造函數(shù)內(nèi)初始化3個(gè)參數(shù)剑鞍,其中 AnnotatedBeanDefinitionReader和 ClassPathBeanDefinitionScanner 是兩個(gè)非常關(guān)鍵的類。一個(gè)是基于注解的bean定義爽醋,一個(gè)是基于路徑的bean掃描蚁署。
我們老樣子逐個(gè)進(jìn)行分析。從這里也開始了無限套娃模式子房。說實(shí)話spring系列的源碼寫的真的很好形用,但也真的很難讀懂。
AnnotatedBeanDefinitionReader:
從構(gòu)造函數(shù)開始:public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { this(registry, getOrCreateEnvironment(registry)); } public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { //基于產(chǎn)生bean的注解证杭,若沒有指定bean的名稱將會(huì)自動(dòng)生成一個(gè)首字母小寫的名稱作為bean的名稱 this.beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE; //Scop的代理模式 this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(); Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); //這里指的是當(dāng)前的環(huán)境變量 this.registry = registry; //條件注入bean this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); return (Environment)(registry instanceof EnvironmentCapable ? ((EnvironmentCapable)registry).getEnvironment() : new StandardEnvironment()); }
先看一下getOrCreateEnvironment方法:
方法主要是判斷了一下當(dāng)前AnnotationConfigServletWebServerApplicationContext是否是EnvironmentCapable子類田度,若是則返回當(dāng)前環(huán)境對(duì)象,若不是則初始化一個(gè)StandardEnvironment解愤。EnvironmentCapable主要是判斷當(dāng)前上限文是否具有提供環(huán)境屬性的能力镇饺。內(nèi)部只有一個(gè)getEnvironment方法,原設(shè)計(jì)是獲取一個(gè)不可修改的環(huán)境對(duì)象送讲。但是在ConfigurableApplicationContext對(duì)其進(jìn)行了重寫奸笤,使獲取的對(duì)象具有可再次定制的能力。
吐槽一下很有迷惑的入?yún)?strong>BeanDefinitionRegistry哼鬓,這個(gè)接口與EnvironmentCapable沒有任何的關(guān)系监右,BeanDefinitionRegistry相當(dāng)于我們?cè)趯懘a時(shí)用的Object接受參數(shù)一樣,是ApplicationContext的父類异希。但是方法內(nèi)直接進(jìn)行了類型強(qiáng)轉(zhuǎn)健盒,雖然也沒有錯(cuò)。
AnnotationBeanNameGenerator:
基于注解生成bean的名稱称簿。若注解指定了則使用注解內(nèi)的扣癣,否則默認(rèn)將類名的首字母變成小寫作為名稱。
AnnotationScopeMetadataResolver:
設(shè)置bean的代理模式憨降,即我們常用的@Scop注解的實(shí)現(xiàn)父虑。在其構(gòu)造函數(shù)內(nèi)默認(rèn)設(shè)置ScopedProxyMode.NO 不使用代理。也就是單例模式授药,即bean是全局唯一的這樣可以避免反復(fù)的創(chuàng)建bean士嚎,提升服務(wù)性能,但也存在線程安全問題悔叽,其實(shí)很好理解莱衩,單例的bean也意味著若存在全局變量,就不能隨意更改否則變更后會(huì)有影響骄蝇。
ScopedProxyMode共有四種類型:
DEFAULT:等同于NO膳殷,不使用代理的單例模式。
NO:單例模式
INTERFACES:jdk動(dòng)態(tài)代理
TARGET_CLASS:CGLAB動(dòng)態(tài)代理
ConditionEvaluator:
自定義創(chuàng)建bean條件,注解@Condition的處理類赚窃〔嵴校可以按照條件進(jìn)行類加載,條件需要單獨(dú)定義勒极,并實(shí)現(xiàn)
Condition接口是掰。
例如:
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
....
return true;
}
}
@Conditional({ MyCondition.class })
@Configuration
public class MyConfig {
@Bean
@Conditional({ MyCondition.class })
public Date date() {
return new Date();
}
}
在springboot項(xiàng)目中很少使用了,springboot提供了更多的@Condition的擴(kuò)展注解辱匿,例如:@ConditionalOnMissingBean键痛,@ConditionalOnProperty,@ConditionalOnBean等匾七。
AnnotationConfigUtils.registerAnnotationConfigProcessors:
在給定的注冊(cè)表中注冊(cè)所有相關(guān)的注解后處理器絮短。比如提供@Autowired,@Value,@Order等注解的支持。所謂的后處理器昨忆,其實(shí)就是相關(guān)注解的支持類丁频。
源碼:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//獲取bean工廠 若是springboot我們這里已經(jīng)知道其為 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//加載順序機(jī)制
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//決定一個(gè)bean定義是否應(yīng)該被視為自動(dòng)裝配的候選時(shí),為這個(gè)BeanFactory設(shè)置一個(gè)自定義的自動(dòng)裝配候選解析器
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
//驗(yàn)證是否包含名稱org.springframework.context.annotation.internalConfigurationAnnotationProcessor的bean
//若沒有則通過registerPostProcessor方法添加到registry中
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//將需要注冊(cè)的bean手動(dòng)封裝成RootBeanDefinition里面邑贴,用于描述bean的屬性和對(duì)bean進(jìn)行操作
//@configuration支持
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
//@Autowired席里、Value注解支持
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
//JSR-250是一個(gè)標(biāo)準(zhǔn),可以理解為java的約定或者說預(yù)留的注解拢驾,網(wǎng)上的定義為資源相關(guān)的處理
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
// JPA約定
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//異步監(jiān)聽器
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
//監(jiān)聽器工廠
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
源碼看起來比較多 但實(shí)際上邏輯很簡單奖磁,為了初始化一些spring自身資源類注解的支持,并注入成bean繁疤。類似于@Resource咖为,@Value等,bean內(nèi)屬性的注入嵌洼,并非@Service的類級(jí)注解案疲。
格外提一點(diǎn)擴(kuò)展知識(shí),上面的源碼中能看到一個(gè)jsr250Present 和 jpaPresent 著其實(shí)是java的兩個(gè)約定封恰。感興趣的可以去了解一下麻养,我只說一點(diǎn),比如:比如我們知道@Resource和@Autowired在很多情況下是可以互換的诺舔。
但是@Resource并非spring的注解鳖昌,而是java自帶的。很早以前就很困惑低飒,為何spring要提供一個(gè)java自身注解的支持许昨,難道不會(huì)和其他的框架或者jar沖突嗎?然而事實(shí)上的確會(huì)沖突褥赊,但這個(gè)@Resource是java制定的資源加載約定注解糕档,相當(dāng)于我提供了一個(gè)接口在這,并且我建議你們遵循這個(gè)約定去實(shí)現(xiàn)它拌喉。
這樣的注解不止@Resource一個(gè)速那,感興趣的可以去了解一下俐银。同理JPA也類似。
單看方法的話會(huì)有點(diǎn)奇怪端仰,這里的返回值不重要捶惜,關(guān)鍵是registerPostProcessor方法。
源碼:
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注入bean
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
方法內(nèi)registry.registerBeanDefinition注冊(cè)了spring的內(nèi)部bean荔烧。
這里講解的順序有問題吱七,下一篇我們將從頂層往下看,這篇是從底層往上看因此鹤竭,會(huì)有點(diǎn)莫名其妙踊餐。若看過源碼或調(diào)試過的小伙伴應(yīng)該知道到這里的時(shí)候其實(shí)已經(jīng)知道了,當(dāng)前上下文中使用的beanFactory是DefaultListableBeanFactory 這是一個(gè)非常關(guān)鍵的類臀稚,bean的整個(gè)加載流程都在內(nèi)部市袖,包括所謂的IOC容器,其實(shí)就是一個(gè)Map烁涌,這些都是后話了苍碟。
AnnotatedBeanDefinitionReader類的解析告一段落。
ClassPathBeanDefinitionScanner:
AnnotatedBeanDefinitionReader實(shí)現(xiàn)了bean內(nèi)屬性的組裝撮执。ClassPathBeanDefinitionScanner實(shí)現(xiàn)的是bean的掃描和加載微峰。
構(gòu)造函數(shù)源碼:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) {
.... 與AnnotatedBeanDefinitionReader相同
this.registry = registry;
if (useDefaultFilters) {
this.registerDefaultFilters();
}
}
protected void registerDefaultFilters() {
//設(shè)置Component注解過濾器
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
this.logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} catch (ClassNotFoundException var4) {
}
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
this.logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} catch (ClassNotFoundException var3) {
}
}
提供:Component、Repository抒钱、Service蜓肆、Controller注解的支持,源碼中只看到了配置Component,因?yàn)槠渌麕讉€(gè)注解都基于Component擴(kuò)展的,另外提供了javaEE 6的ManagedBean注解和JSR-330的Named注解支持谋币。
感興趣的可以去了解一下 JSR和JPA協(xié)議仗扬。
AnnotationConfigServletWebServerApplicationContext 類講解到此結(jié)束。
回到上面UMl圖蕾额,可以看到其擁有一個(gè)復(fù)雜的繼承關(guān)系早芭,并且上面也留了一個(gè)疑問,加載過程中的beanFactory是在什么地方初始化的诅蝶?
下面將依次看一下其父類的無參構(gòu)造函數(shù)都做了啥(接口除外)退个,大部分接口內(nèi)部沒有邏輯代碼。
按從下往上的方式去看:
ServletWebServerApplicationContext 無操作调炬。
GenericWebApplicationContext 無操作
GenericApplicationContext
源碼:
public GenericApplicationContext() {
this.customClassLoader = false;
this.refreshed = new AtomicBoolean();
// 初始化bean工廠
this.beanFactory = new DefaultListableBeanFactory();
}
這里已經(jīng)知道上下文中使用的beanFactory是DefaultListableBeanFactory類
AbstractApplicationContext
源碼:
public AbstractApplicationContext() {
this.logger = LogFactory.getLog(this.getClass());
this.id = ObjectUtils.identityToString(this);
this.displayName = ObjectUtils.identityToString(this);
this.beanFactoryPostProcessors = new ArrayList();
this.active = new AtomicBoolean();
this.closed = new AtomicBoolean();
this.startupShutdownMonitor = new Object();
this.applicationListeners = new LinkedHashSet();
//特殊資源路徑的加載處理语盈,非classpath*:下的資源,如:file:C:/context.xml
this.resourcePatternResolver = this.getResourcePatternResolver();
}
DefaultResourceLoader
源碼:
public DefaultResourceLoader() {
this.classLoader = ClassUtils.getDefaultClassLoader();
}
-
DefaultListableBeanFactory解析
構(gòu)造函數(shù)源碼:
注釋理解來自于源碼:
public DefaultListableBeanFactory() {
// 用于檢查bean定義是否為自動(dòng)裝配候選的解析程序
this.autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
//從依賴項(xiàng)類型映射到相應(yīng)的自動(dòng)裝配值
this.resolvableDependencies = new ConcurrentHashMap(16);
//Bean定義對(duì)象的映射缰泡,以Bean名稱為鍵刀荒。
this.beanDefinitionMap = new ConcurrentHashMap(256);
//根據(jù)名稱合并 BeanDefinitionHolder持有的bean
this.mergedBeanDefinitionHolders = new ConcurrentHashMap(256);
//單例和非單例Bean名稱的映射,按依賴項(xiàng)類型進(jìn)行鍵控
this.allBeanNamesByType = new ConcurrentHashMap(64);
//僅依賴單例的bean名稱的映射,按依賴項(xiàng)類型進(jìn)行鍵控
this.singletonBeanNamesByType = new ConcurrentHashMap(64);
//Bean定義名稱列表缠借,按注冊(cè)順序
this.beanDefinitionNames = new ArrayList(256);
//手動(dòng)注冊(cè)的單例的名稱列表资溃,按注冊(cè)順序。
this.manualSingletonNames = new LinkedHashSet(16);
}
這個(gè)是jar包中的源碼烈炭,若從github獲取的源碼構(gòu)造函數(shù)內(nèi)可能并沒有溶锭,而是通過餓漢式的模式直接在定義屬性的時(shí)候就初始化了,這樣雖然寫著方便符隙,但看著并不直觀趴捅。
構(gòu)造函數(shù)內(nèi)初始化的Map們就是口中常說的IOC容器
那么bean的循環(huán)依賴時(shí)如何被解決的呢?先留一個(gè)疑問霹疫,在將bean加載的流程時(shí)候再說拱绑。
DefaultListableBeanFactory也有著很復(fù)雜的繼承關(guān)系,下面將結(jié)合UML圖進(jìn)行講解。
只看圖中藍(lán)色的實(shí)體類繼承關(guān)系。逐個(gè)類的構(gòu)造函數(shù)查看颈畸。構(gòu)造函數(shù)未必都是無參的采桃,具體執(zhí)行的哪一個(gè)要看子類是否有傳入特定參數(shù)般渡。
一般情況下,在非工具的實(shí)體類中很少有 static 的靜態(tài)代碼塊,因此不需要刻意去尋找。一般都是通過構(gòu)造函數(shù)完成初始化吧恃。
AbstractAutowireCapableBeanFactory
源碼:
public AbstractAutowireCapableBeanFactory() {
//基于CGLB的bean動(dòng)態(tài)代理創(chuàng)建(策略模式)
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
//獲取方法或構(gòu)造函數(shù)的參數(shù)名稱,這里默認(rèn)通過java反射機(jī)制
this.parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
//是否自動(dòng)嘗試解析bean之間的循環(huán)依賴
this.allowCircularReferences = true;
//在循環(huán)依賴的時(shí)候麻诀,是否可以注入原始的bean痕寓,應(yīng)該是為進(jìn)行屬性賦值的原始bean
this.allowRawInjectionDespiteWrapping = false;
//根據(jù)類型忽略相關(guān)的實(shí)現(xiàn)
this.ignoredDependencyTypes = new HashSet();
//忽略相關(guān)接口
this.ignoredDependencyInterfaces = new HashSet();
// 當(dāng)前創(chuàng)建的bean的名稱,用于隱式依賴項(xiàng)注冊(cè)
// 從用戶指定的Supplier回調(diào)觸發(fā)的getBean等調(diào)用上
this.currentlyCreatedBean = new NamedThreadLocal("Currently created bean");
//未完成的FactoryBean實(shí)例的緩存:BeanWrapper的FactoryBean名稱
this.factoryBeanInstanceCache = new ConcurrentHashMap();
//按工廠類別緩存候選工廠方法
this.factoryMethodCandidateCache = new ConcurrentHashMap();
//過濾后的PropertyDescriptor的緩存:Bean類到PropertyDescriptor數(shù)組蝇闭。
this.filteredPropertyDescriptorsCache = new ConcurrentHashMap();
this.ignoreDependencyInterface(BeanNameAware.class);
this.ignoreDependencyInterface(BeanFactoryAware.class);
this.ignoreDependencyInterface(BeanClassLoaderAware.class);
}
源碼中初始化了bean的代理模式呻率、bean循環(huán)依賴處理配置,以及緩存bean的相關(guān)工廠信息呻引。
最后忽略了BeanNameAware礼仗、BeanFactoryAware 、 BeanClassLoaderAware三個(gè)接口的相關(guān)類苞七。
暫時(shí)原因并不清楚藐守,為何要排除挪丢。這里暫時(shí)先不說蹂风,等說道bean加載的時(shí)候在說。
小結(jié)
本文主要講解了上下文構(gòu)建類的初始化過程乾蓬,到此仍在進(jìn)行bean加載前的準(zhǔn)備工作惠啄。上篇文章中初始化的環(huán)境對(duì)象被注入到上限文類中,繼續(xù)推進(jìn)初始化流程。
本文主要幾點(diǎn):
1.資源類注解@Resouce撵渡、@Value等融柬,背后的支持類初始化完成。
2.bean加載相關(guān)注解趋距,@Component粒氧、@Service,背后的支持類初始化节腐。
3.基于condition的條件注入
4.DefaultListableBeanFactory工廠類的初始化外盯。所謂IOC容器也是在這里進(jìn)行初始化。且內(nèi)部涉及到bean的循環(huán)依賴配置翼雀。
存留問題:
1.為何要在工廠類初始化的時(shí)候饱苟,移除BeanNameAware、BeanFactoryAware 狼渊、 BeanClassLoaderAware三個(gè)接口的加載箱熬?
2.spring如何解決循環(huán)依賴的問題
3.未完成的bean是如何保存的