DI运行时序
概念
依赖注入,就是Spring从 Ioc容器里面,取出需要的bean(一个实例) ,然后注入/装配到 需要的地方。
BeanFactory
BeanFactory 则定义了最基本的功能,向其他功能提供 getBean( arge....)的功能定义,这是Spring中,IOC概念的重要接口,它的子类根据自己的需求多样化实现了getBean。
/**
* BeanFactory作为最顶层的一个接口类,它定义了IOC容器的基本功能规范,BeanFactory 有三个子类
*/
public interface BeanFactory {
// BeanFactory 提供了多个 getBean 接口定义,所有的beanFactory都必须要实现这些接口
Object getBean(String name) throws BeansException;
......
}
AbstractBeanFactory (简称 AbBD)
AbBD 是一个抽象类,也是对BeanFactory 进行实现的基类
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory{
//对BeanFactory#getBean()的实现
getBean(....){
doGetBean( ...);
}
// 这是getBean 的核心实现,也是IOC 获得Bean的核心方法
doGetBean( ){
......
}
}
实现层级
[图片上传失败...(image-97a893-1592449507292)]
- 从父类接口来看,AbBD 继承了 父接口 HierarchicalBeanFactory ,这表示,AbBD 拥有父层级BeanFactory功能(这个功能允许 doGetBean()方法中, 在查找 beanDefinition时,先委派给 父类 BeanFactory 进行 beanDefinition 查找 ,类似于 双亲委派模式)
- AbBD 继承了 抽象类FactoryBeanRegistrySupport,拥有了 通过 预先定义的单例FactoryBean 获取 单例 instance 的能力
- [图片上传失败...(image-caefb6-1592449507298)]
核心方法 AbBD#doGetBean
- 先从总体上浏览一下,doGetBean的业务流程 分为三个部:
if (是否存在于单例池中){
。。。。。
}else{
如果没有,则进行常态创建
}
if (进行类型检查){
。。。。。
}
return (T)bean;
接下来,看看具体代码实现:
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
//如果指定的是别名,将别名转换为规范的Bean名称
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/**
* 即时检查单例缓存,是否手动注册过的单例
* 这个方法内部会对未创建的单例bean进行一系列的创建、缓存并返回
*/
Object sharedInstance = getSingleton(beanName);
...
- AbBD#getSingleton(beanName)的实现如下:
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
/**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*
*
* 锁住该单例map,从预备单例池中取出该单例,进行单例创建
这个单例池,有很多的 单例会提前加入进来,比如,在 AbstractApplication#refresh#prepareBeanFactory的时候,会有很多容器相关的单例对象加入到这个map池中,比如,“environment”,“systemProperties”等。
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
//从单例池map中,获得单例,如果单例池中没有该单例 且 单例创建set中油存在该单例
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//进入if 锁住该单例map,从预备单例池中取出该单例,进行单例创建
synchronized (this.singletonObjects) {
//从 单例预备池中,取出单例
singletonObject = this.earlySingletonObjects.get(beanName);
//如果不在预备池中 且 该bean允许进行 early references 即时连接
if (singletonObject == null && allowEarlyReference) {
//进入if 根据 beanName 获得单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//单例工厂不为null 进行
if (singletonFactory != null) {
//singletonFactory.getObject 委托给子类去实现 获得单例
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
这是一个向单例池中放入单例的场景,而且是IOC容器初始化的时候放进去的,可以认为是Spring自己放入的,对于应用十分基础且必要的单例对象。
[图片上传失败...(image-5243d6-1592449507298)]
然后,我们再跳回到 doGetBean方法里,继续看下去,如果能够获取到单例,则进入if分支:
……
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
/**
* 如果 name在 Set<String> singletonsCurrentlyInCreation 创建中的列表,这个逻辑很好理解
* 会提示,还没有该单例处于创建中
*/
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**
* 获取给定Bean的单例实例,如果sharedInstance是FactoryBean,则通过FactoryBean的获得最终的目标bean,如果不是FactoryBean,则直接返回该sharedInstance
* 注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是创建创建对象的工厂Bean,两者之间有区别
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
- bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 这行代码的具体实现如下:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 检查name 是否由&开头,却又不是 FactoryBean,&这个符号不用多说,是由BeanFactory老祖宗定下的
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
// 由 & 开始,但又不是 FactoryBean 就报错
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
/**
* 对 beaninstance 进行最终处理,如果是 普通的bean ,就直接返回
* 如果是 Factorybean 就
* 1.先从 factoryBeanObjectCache 中获取缓存
* 2.如果没有缓存,再通过工厂去获得 instance
*/
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
// 从缓存中获取 instance,这个是由 FactoryBeanRegistrySupport 提供的
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
- 到了这里,可以看到 sharedInstance != null && args == null 判断就走完了,如果没有单例缓存池里找到,则进入到else 语句
/**
* 如果 sharedInstance在单例 中找不到
* todo 到了这个else,可以表示 这个instance 非单例吗?
*/
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
/**
* 检查 是否创建中
* 如果这个 beanname 位于 正在创建池中,这个池子由ThreadLocal实现,则抛出异常
* 根据其他资料看,有说法 : 如果当前的bean已经被创建,获取会失败,表示可能有别的bean在引用该bean
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//父beanFactory存在,且 benaDefinition没有在父beanFactory中
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
/**
// 如果该beanFactory 具有父beanFactory层级,则委托给父类先进行查询,类似于双亲委派模式
// AbstractBeanFactory impl ConfigurableBeanFactory impl HierarchicalBeanFactory
HierarchicalBeanFactory 定义了beanFactory 是具有父BeanFactory层级的。
*/
if (parentBeanFactory instanceof AbstractBeanFactory) {
//遍历祖先,进行查询
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//如果参数 不为 null,则委托给父工厂
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
//bean的真实类型
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
//这里表示args和requiredType都为null,直接通过得到的bean的名字去获取实例
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
/**
* 如果不检查类型,则 mergedBeanDefinitions中移除该beanname,
* 同时加入到 this.alreadyCreated.add(beanName); 已创建的缓存池中
*/
markBeanAsCreated(beanName);
}
try {
/**
* 从本地拿到 BD 合并父子bean的定义
*/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查是否抽象类 -》 抽象类不能被实例化,会抛出错误
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// ************** 先 遍历 bean的依赖项、*******************
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 检查循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
/**
* 向bean 注册 依赖bean
*/
registerDependentBean(dep, beanName);
try {
//根据依赖beanname,创建 依赖的bean实例
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// ************** bean的依赖项遍历创建完成*******************
// Create bean instance.
// 创建 bean 实例
if (mbd.isSingleton()) {
//从单例池中获取,或者创建一个单例,并注册到单例池map, 这里使用了lambda 实现了一个ObjectBeanFactory
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.
//最后从缓存中移除对应的实例原因有:
//1.每当有bean在创建时,允许循环参考来解析对应的beanDefinition
//2.删除临时引用该bean的bean
destroySingleton(beanName);
throw ex;
}
});
//获得一个 bean 实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果是常态多例的 bd
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
//在实例化之前执行一次 before
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//实例化之后,执行一次 after
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//如果是其他scope
else {
//获得 bean 的作用域
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
//进行类型判断
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
//返回 bean
return (T) bean;
}