spring ioc源码分析

清晰图或者源码可以加我Q群:940577921 获取

图片1.png

Spring IOC介绍
IoC也称为依赖注入(dependency injection, DI)。它是一个对象定义依赖关系的过程,也就是说,对象只通过构造函数参数、工厂方法的参数或对象实例构造或从工厂方法返回后在对象实例上设置的属性来定义它们所使用的其他对象。然后容器在创建bean时注入这些依赖项。这个过程基本上是bean的逆过程,因此称为控制反转(IoC)。
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。
IoC容器理念:通过容器将对象的构建方式统一,并且自动维护对象的依赖关系。由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
回顾Bean的使用
bean的配置
// 注册一个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.实现FactoryBean
FactoryBean和BeanFactory的区别,什么情况下返回FactoryBean,什么情况返回调用getObject()的结果
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的创建 初始化 销毁
1.bean的注册原理
bean是如何注册到容器中的?
BeanDefinition 承载bean的信息,并注册到BeanDefinitionRegistry注册器中,bean工厂获取到注册器中对应bean的信息,才能生产bean
BeanDefinition (Bean定义) 承载bean的属性信息
BeanDefinitionRegistry(Bean注册器) bean的id作为key注册
AliasRegistry (别名注册器) bean的name作为key注册
BeanDefinitionReader(Bean定义读取) 读取配置文件
Beanfactory (bean工厂) 生产bean

示例

//创建一个简单注册器
//BeanDefinitionRegistry register = new SimpleBeanDefinitionRegistry();
//实现注册器的工厂
BeanDefinitionRegistry registry = new DefaultListableBeanFactory();
//创建bean定义读取器
BeanDefinitionReader reader = new XmlBeanDefinitionReader(register);
// 创建资源读取器
//DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
// 获取资源
//Resource xmlResource = resourceLoader.getResource("spring.xml");
reader.loadBeanDefinitions("spring.xml");
// 装载Bean的定义
reader.loadBeanDefinitions(xmlResource);
// 打印构建的Bean 名称
System.out.println(Arrays.toString(register.getBeanDefinitionNames());

// 工厂调用getBean方法
((DefaultListableBeanFactory) registry).getBean("user")

// 注册一个bean
registry.registerBeanDefinition("fox",new RootBeanDefinition(Fox.class));

2.bean的创建流程
Bean创建时序图


图片2.png

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

markBeanAsCreated(beanName);   //标记Bean正要创建
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args); 是不是抽象的
String[] dependsOn = mbd.getDependsOn();  有没有依赖,先实例化依赖bean

创建bean实例

DefaultSingletonBeanRegistry#getSingleton

通过工厂获取对象

singletonObject = singletonFactory.getObject();

AbstractAutowireCapableBeanFactory#createBean

Instantiate the bean.

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

AbstractAutowireCapableBeanFactory#createBeanInstance

调用无参构造器

AbstractAutowireCapableBeanFactory#instantiateBean

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

//填充bean由 IoC 容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

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

image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,881评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,052评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,598评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,407评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,823评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,872评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,037评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,778评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,505评论 1 247
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,745评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,233评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,231评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,141评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,939评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,954评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,784评论 2 275

推荐阅读更多精彩内容