spring ioc源碼分析

清晰圖或者源碼可以加我Q群:940577921 獲取

圖片1.png

Spring IOC介紹
IoC也稱為依賴注入(dependency injection, DI)绘盟。它是一個(gè)對(duì)象定義依賴關(guān)系的過程,也就是說(shuō)弄喘,對(duì)象只通過構(gòu)造函數(shù)參數(shù)茅主、工廠方法的參數(shù)或?qū)ο髮?shí)例構(gòu)造或從工廠方法返回后在對(duì)象實(shí)例上設(shè)置的屬性來(lái)定義它們所使用的其他對(duì)象蒙具。然后容器在創(chuàng)建bean時(shí)注入這些依賴項(xiàng)冒萄。這個(gè)過程基本上是bean的逆過程池摧,因此稱為控制反轉(zhuǎn)(IoC)。
在Spring中仓洼,構(gòu)成應(yīng)用程序主干并由Spring IoC容器管理的對(duì)象稱為bean介陶。bean是由Spring IoC容器實(shí)例化、組裝和管理的對(duì)象色建。
IoC容器理念:通過容器將對(duì)象的構(gòu)建方式統(tǒng)一,并且自動(dòng)維護(hù)對(duì)象的依賴關(guān)系舌缤。由 IoC 容器幫對(duì)象找相應(yīng)的依賴對(duì)象并注入箕戳,而不是由對(duì)象主動(dòng)去找。
回顧Bean的使用
bean的配置
// 注冊(cè)一個(gè)bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));
1.xml
<bean id="user" class="com.jiagouedu.bean.User"/>

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

2.實(shí)現(xiàn)FactoryBean
FactoryBean和BeanFactory的區(qū)別国撵,什么情況下返回FactoryBean陵吸,什么情況返回調(diào)用getObject()的結(jié)果
3.@Component ,掃描包
@ComponentScan("com.jiagouedu")
@Configuration
public class AppConfig {
}

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
4.@Bean
5.@Import
@Import(value = {MyImportBeanDefinitionRegistrar.class,MyImportSelector.class})
?ImportBeanDefinitionRegistrar

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new RootBeanDefinition(UserServiceImpl.class);
registry.registerBeanDefinition("userServiceImpl",beanDefinition);
}
}
?ImportSelector
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.jiagouedu.bean.Cat"};
}
}
bean的生命周期
bean的生命周期: bean的創(chuàng)建 初始化 銷毀
1.bean的注冊(cè)原理
bean是如何注冊(cè)到容器中的介牙?
BeanDefinition 承載bean的信息壮虫,并注冊(cè)到BeanDefinitionRegistry注冊(cè)器中,bean工廠獲取到注冊(cè)器中對(duì)應(yīng)bean的信息,才能生產(chǎn)bean
BeanDefinition (Bean定義) 承載bean的屬性信息
BeanDefinitionRegistry(Bean注冊(cè)器) bean的id作為key注冊(cè)
AliasRegistry (別名注冊(cè)器) bean的name作為key注冊(cè)
BeanDefinitionReader(Bean定義讀惹羲啤) 讀取配置文件
Beanfactory (bean工廠) 生產(chǎn)bean

示例

//創(chuàng)建一個(gè)簡(jiǎn)單注冊(cè)器
//BeanDefinitionRegistry register = new SimpleBeanDefinitionRegistry();
//實(shí)現(xiàn)注冊(cè)器的工廠
BeanDefinitionRegistry registry = new DefaultListableBeanFactory();
//創(chuàng)建bean定義讀取器
BeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
// 創(chuàng)建資源讀取器
//DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
// 獲取資源
//Resource xmlResource = resourceLoader.getResource("spring.xml");
reader.loadBeanDefinitions("spring.xml");
// 裝載Bean的定義
reader.loadBeanDefinitions(xmlResource);
// 打印構(gòu)建的Bean 名稱
System.out.println(Arrays.toString(register.getBeanDefinitionNames());

// 工廠調(diào)用getBean方法
((DefaultListableBeanFactory) registry).getBean("user")

// 注冊(cè)一個(gè)bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));

2.bean的創(chuàng)建流程
Bean創(chuàng)建時(shí)序圖


圖片2.png

Debug跟蹤流程:
AbstractApplicationContext#finishBeanFactoryInitialization
ConfigurableListableBeanFactory#preInstantiateSingletons
AbstractBeanFactory#getBean(java.lang.String)
AbstractBeanFactory#doGetBean

markBeanAsCreated(beanName);   //標(biāo)記Bean正要?jiǎng)?chuàng)建
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args); 是不是抽象的
String[] dependsOn = mbd.getDependsOn();  有沒有依賴剩拢,先實(shí)例化依賴bean

創(chuàng)建bean實(shí)例

DefaultSingletonBeanRegistry#getSingleton

通過工廠獲取對(duì)象

singletonObject = singletonFactory.getObject();

AbstractAutowireCapableBeanFactory#createBean

Instantiate the bean.

AbstractAutowireCapableBeanFactory#doCreateBean
# 包裝的bean BeanWrapper
instanceWrapper=createBeanInstance(beanName, mbd, args);

AbstractAutowireCapableBeanFactory#createBeanInstance

調(diào)用無(wú)參構(gòu)造器

AbstractAutowireCapableBeanFactory#instantiateBean

#反射
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

//填充bean由 IoC 容器幫對(duì)象找相應(yīng)的依賴對(duì)象并注入,而不是由對(duì)象主動(dòng)去找饶唤。

populateBean(beanName, mbd, instanceWrapper);
// 初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末徐伐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子募狂,更是在濱河造成了極大的恐慌办素,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祸穷,死亡現(xiàn)場(chǎng)離奇詭異性穿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)雷滚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門季二,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人揭措,你說(shuō)我怎么就攤上這事胯舷。” “怎么了绊含?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵桑嘶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我躬充,道長(zhǎng)逃顶,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任充甚,我火速辦了婚禮以政,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伴找。我一直安慰自己盈蛮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布技矮。 她就那樣靜靜地躺著抖誉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衰倦。 梳的紋絲不亂的頭發(fā)上袒炉,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音樊零,去河邊找鬼我磁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的夺艰。 我是一名探鬼主播芋哭,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼劲适!你這毒婦竟也來(lái)了楷掉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤霞势,失蹤者是張志新(化名)和其女友劉穎烹植,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愕贡,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡草雕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了固以。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墩虹。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖憨琳,靈堂內(nèi)的尸體忽然破棺而出诫钓,到底是詐尸還是另有隱情,我是刑警寧澤篙螟,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布菌湃,位于F島的核電站,受9級(jí)特大地震影響遍略,放射性物質(zhì)發(fā)生泄漏惧所。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一绪杏、第九天 我趴在偏房一處隱蔽的房頂上張望下愈。 院中可真熱鬧,春花似錦蕾久、人聲如沸势似。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叫编。三九已至,卻和暖如春霹抛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卷谈。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工杯拐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓端逼,卻偏偏與公主長(zhǎng)得像朗兵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子顶滩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容