1.测试环境搭建
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
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.在创建容器的那行打断点,跟进
- 进入AnnotationConfigApplicationContext的构造方法,跟踪到调用refresh()
- 跟进refresh()方法,可以看到容器的刷新所经历的大致步骤
- 直接跟进到finishBeanFactoryInitialization(beanFactory)方法
- 跟进到getBean(beanName)方法,对应行号为760
- 跟进getBean方法,发现调用的是doGetBean(String)方法,进下跟进。
- createBean(beanName, mbd, args);第317行lambda表达式跟进
- 501行调用doCreateBean(beanName, mbdToUse, args);跟进
- 在doCreateBean(beanName, mbdToUse, args);中第536行打个断点,按F8放行,观察此方法的参数beanName的值,直接到为person.
- 跟进第541行,调用createBeanInstance(beanName, mbd, args);
- 跟进第1103行,调用instantiateUsingFactoryMethod(beanName, mbd, args);跟进
- 跟进instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);方法调用
- 579行调用this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse),跟进instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);方法
- org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(RootBeanDefinition, String, BeanFactory, Object, Method, Object…)中第154行通过反射调用工厂方法创建对象
- 返回到第9步的方法调用,进行往下走,第578行调用populateBean(beanName, mbd, instanceWrapper);填充的bean的属性(如set方法,@Autowired注入等),第579行调用initialization callback方法
- 返回到第6步的lambda表达式执行完,进入getSingleton方法
- 到getSingleton方法的第254行,将新创建的单例bean加入的IOC容器(大Map)中


至此普通的单例bean的创建,初始化并放入到IOC容器的整个流程就完成了,之后就是通过的容器的getBean方法获取到被创建的对象进行方法调用,再到容器的销毁前将其销毁。