设计
假设我们自己来设计怎么去创建bean,有几种方案可以提供
- 每次需要的时候new一个对象(这个也是我们常用的)
- 对第一个进行升级,把new对象的工作交给工厂
- 假设我们的对象是稳定的,而且是线程安全的,那么我们可以使用同一个对象,可以把这个对象缓存起来。放到一个容器,每次需要用的时候拿出来
spring做的事情就是帮我们创建对象,并且把对象缓存到一个Map容器中,需要的时候从容器获取即可。
上图
关键的前置条件
在bean创建之前有些工作时必须完成的,它们是创建bean的必要条件
- BeanDefinition的收集已经完成(需要创建那些bean)
- 工厂初始化完成(容器的准备)
- 配置加载完成(bean中属性的注入)
。。。
步骤
- 循环所有的beanName,对每个beanName进行创建
.........省略
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
....
// getBean就是创建对象操作
getBean(beanName);
....
}
}
.........
- 先从缓存中拿取实例,如果缓存中有,直接返回,如果缓存中没有,创建对象
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
.........
// 从缓存中拿取实例
Object sharedInstance = getSingleton(beanName);
.........
// 重点看这里,大部分情况都是单例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 看这里
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
// factoryBean 的getObject 方法获取的实例 走这里
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
.........
- 最终使用java的反射api来创建对象
....
// 实例化对象
return ctor.newInstance(argsWithDefaultValues);
...
- 创建对象完成之后放入缓存
....
if (newSingleton) {
// 放入缓存
addSingleton(beanName, singletonObject);
}
...
- 上述主要讲了spring对象单例的创建