初探Spring-IOC源码之普通单例bean的生命周期

1.测试环境搭建

  • pom.xml
<dependency>
  		<groupId>org.springframework</groupId>
  		<artifactId>spring-context</artifactId>
  		<version>5.0.6.RELEASE</version>
</dependency>
  • 新建一个配置类和一个Person类
public class Person {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}
@Configuration
public class AppConfig {

	@Bean
	public Person person() {
		return new Person();
	}
}
  • 新建一个测试用例
/**
 * AnnotationConfigApplicationContext入口,测试spring-IOC源码执行流程
 */
public class AnnotationConfigApplicationContextEntry {

	@Test
	public void entry() {
		
		// Create the container
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
		
		// retrieve the bean of Person class
		Object bean = context.getBean("person");
		
		//close the container
		context.close();
	}
	
}

2.在创建容器的那行打断点,跟进

  1. 进入AnnotationConfigApplicationContext的构造方法,跟踪到调用refresh()
    在这里插入图片描述
  2. 跟进refresh()方法,可以看到容器的刷新所经历的大致步骤
    在这里插入图片描述
  3. 直接跟进到finishBeanFactoryInitialization(beanFactory)方法
    在这里插入图片描述
  4. 跟进到getBean(beanName)方法,对应行号为760
    在这里插入图片描述
  5. 跟进getBean方法,发现调用的是doGetBean(String)方法,进下跟进。
  6. createBean(beanName, mbd, args);第317行lambda表达式跟进
    在这里插入图片描述
  7. 501行调用doCreateBean(beanName, mbdToUse, args);跟进
    在这里插入图片描述
  8. 在doCreateBean(beanName, mbdToUse, args);中第536行打个断点,按F8放行,观察此方法的参数beanName的值,直接到为person.
  9. 跟进第541行,调用createBeanInstance(beanName, mbd, args);
    在这里插入图片描述
  10. 跟进第1103行,调用instantiateUsingFactoryMethod(beanName, mbd, args);跟进
    在这里插入图片描述
  11. 跟进instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);方法调用
    在这里插入图片描述
  12. 579行调用this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse),跟进instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);方法
    在这里插入图片描述
  13. org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(RootBeanDefinition, String, BeanFactory, Object, Method, Object…)中第154行通过反射调用工厂方法创建对象
    在这里插入图片描述
  14. 返回到第9步的方法调用,进行往下走,第578行调用populateBean(beanName, mbd, instanceWrapper);填充的bean的属性(如set方法,@Autowired注入等),第579行调用initialization callback方法
    在这里插入图片描述
  15. 返回到第6步的lambda表达式执行完,进入getSingleton方法
    在这里插入图片描述
  16. 到getSingleton方法的第254行,将新创建的单例bean加入的IOC容器(大Map)中
    在这里插入图片描述
    在这里插入图片描述
    至此普通的单例bean的创建,初始化并放入到IOC容器的整个流程就完成了,之后就是通过的容器的getBean方法获取到被创建的对象进行方法调用,再到容器的销毁前将其销毁。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值