书接上文我对IoC感兴趣的2个点别离是

  • IoC是怎么获取bean信息,并治理bean的
  • IoC引以为豪的依赖注入

    • IoC是怎么解决循环依赖的(没错齐全是因为网上说面试爱问)

    当初曾经解决了第一个问题了,上面来剖析下第二个问题--依赖注入

依赖注入简略来说就是本人创建对象交给Spring容器治理。那必定就有以下几个步骤了

  1. 创建对象
  2. 将对象所依赖的对象注入进来
  3. 怎么解决循环依赖的问题的
    本篇也将围绕着三点开展了。
    ps:源码剖析乃集体总结,如果有任何不对的中央,欢送分割我探讨

创建对象

在上一篇中曾经理解到了Spring是如何获取bean的各项信息,并把信息存储在DefaultListableBeanFactory中了。

此时Spring还未初始化实现还记得AbstractApplicationContext#refresh办法么。

他会在finishBeanFactoryInitialization中创建对象

// Instantiate all remaining (non-lazy-init) singletons.//实例化所有残余的(非提早初始化)单例。finishBeanFactoryInitialization(beanFactory);
@Overridepublic void preInstantiateSingletons() throws BeansException {   if (logger.isTraceEnabled()) {      logger.trace("Pre-instantiating singletons in " + this);   }   // Iterate over a copy to allow for init methods which in turn register new bean definitions.   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);   // Trigger initialization of all non-lazy singleton beans...   for (String beanName : beanNames) {      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//形象,非单例,不是提早加载的过滤         if (isFactoryBean(beanName)) {            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);            if (bean instanceof FactoryBean) {               FactoryBean<?> factory = (FactoryBean<?>) bean;               boolean isEagerInit;               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {                  isEagerInit = AccessController.doPrivileged(                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,                        getAccessControlContext());               }               else {                  isEagerInit = (factory instanceof SmartFactoryBean &&                        ((SmartFactoryBean<?>) factory).isEagerInit());               }               if (isEagerInit) {                  getBean(beanName);               }            }         }         else {            getBean(beanName);//一般bean进入这个办法         }      }   }   // Trigger post-initialization callback for all applicable beans...为所有实用的 bean 触发初始化后回调   for (String beanName : beanNames) {      Object singletonInstance = getSingleton(beanName);      if (singletonInstance instanceof SmartInitializingSingleton) {         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;         if (System.getSecurityManager() != null) {            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {               smartSingleton.afterSingletonsInstantiated();               return null;            }, getAccessControlContext());         }         else {            smartSingleton.afterSingletonsInstantiated();         }      }   }}

随后会进入AbstractBeanFactory#doGetBean,他是十分外围的一个办法,大抵流程如下,先从本容器中查问,没有,就去父容器查问,以此类推。查到了,就去曾经创立的bean中singletonObjects(key为beanName,value为创立好的bean)中寻找,有就间接返回,找不到就再创立,能够了解为,调用这个办法肯定能获取到须要的bean。

protected <T> T doGetBean(      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)      throws BeansException {   String beanName = transformedBeanName(name);   Object bean;   // Eagerly check singleton cache for manually registered singletons.|查问缓存中是否   Object sharedInstance = getSingleton(beanName);   if (sharedInstance != null && args == null) {      if (logger.isTraceEnabled()) {         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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);   }   else {      // Fail if we're already creating this bean instance:      // We're assumably within a circular reference.      if (isPrototypeCurrentlyInCreation(beanName)) {         throw new BeanCurrentlyInCreationException(beanName);      }      // Check if bean definition exists in this factory.|查看是否能在以后BeanFactory中获得须要的Bean。没有找到就去父容器去取      BeanFactory parentBeanFactory = getParentBeanFactory();      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {         // Not found -> check parent.         String nameToLookup = originalBeanName(name);         if (parentBeanFactory instanceof AbstractBeanFactory) {            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(                  nameToLookup, requiredType, args, typeCheckOnly);         }         //如果以后beanFactory中有bean         else if (args != null) {            // Delegation to parent with explicit args.            return (T) parentBeanFactory.getBean(nameToLookup, args);         }         else if (requiredType != null) {            // No args -> delegate to standard getBean method.            return parentBeanFactory.getBean(nameToLookup, requiredType);         }         else {            return (T) parentBeanFactory.getBean(nameToLookup);         }      }      if (!typeCheckOnly) {         markBeanAsCreated(beanName);      }      try {         //依据BeanName获取BeanDefinition         RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);         checkMergedBeanDefinition(mbd, beanName, args);         // Guarantee initialization of beans that the current bean depends on.|获取以后bean依赖的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 + "'");               }               registerDependentBean(dep, beanName);               try {                  getBean(dep);               }               catch (NoSuchBeanDefinitionException ex) {                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);               }            }         }         // Create bean instance.         if (mbd.isSingleton()) {//TODO 创立bean,配置bean外围办法            sharedInstance = getSingleton(beanName, () -> {               try {                  return createBean(beanName, mbd, args);//创立bean               }               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;               }            });            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);         }         //创立property bean的中央         else if (mbd.isPrototype()) {            // It's a prototype -> create a new instance.            Object prototypeInstance = null;            try {               beforePrototypeCreation(beanName);               prototypeInstance = createBean(beanName, mbd, args);            }            finally {               afterPrototypeCreation(beanName);            }            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);         }         else {            String scopeName = mbd.getScope();            if (!StringUtils.hasLength(scopeName)) {               throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");            }            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;      }   }   //此时bean曾经蕴含了依赖关系的bean   // Check if required type matches the type of the actual bean instance.|查看所需类型是否与理论 bean 实例的类型匹配   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());      }   }   return (T) bean;}

而后会调用AbstractAutowireCapableBeanFactory#doCreateBean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)      throws BeanCreationException {   // Instantiate the bean.持有创立进去的Bean对象   BeanWrapper instanceWrapper = null;   if (mbd.isSingleton()) {//单例,先把缓存中的同名Bean革除      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);   }   //TODO 理论创立bean   if (instanceWrapper == null) {      instanceWrapper = createBeanInstance(beanName, mbd, args);   }   Object bean = instanceWrapper.getWrappedInstance();   Class<?> beanType = instanceWrapper.getWrappedClass();   if (beanType != NullBean.class) {      mbd.resolvedTargetType = beanType;   }   // Allow post-processors to modify the merged bean definition.   synchronized (mbd.postProcessingLock) {      if (!mbd.postProcessed) {         try {            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);         }         catch (Throwable ex) {            throw new BeanCreationException(mbd.getResourceDescription(), beanName,                  "Post-processing of merged bean definition failed", ex);         }         mbd.postProcessed = true;      }   }   // Eagerly cache singletons to be able to resolve circular references   // even when triggered by lifecycle interfaces like BeanFactoryAware.   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&         isSingletonCurrentlyInCreation(beanName));   if (earlySingletonExposure) {      if (logger.isTraceEnabled()) {         logger.trace("Eagerly caching bean '" + beanName +               "' to allow for resolving potential circular references");      }      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));   }   // Initialize the bean instance.|依赖注入在这里产生   Object exposedObject = bean;   try {      populateBean(beanName, mbd, instanceWrapper);      exposedObject = initializeBean(beanName, exposedObject, mbd);   }   catch (Throwable ex) {      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {         throw (BeanCreationException) ex;      }      else {         throw new BeanCreationException(               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);      }   }   if (earlySingletonExposure) {      Object earlySingletonReference = getSingleton(beanName, false);      if (earlySingletonReference != null) {         if (exposedObject == bean) {            exposedObject = earlySingletonReference;         }         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {            String[] dependentBeans = getDependentBeans(beanName);            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);            for (String dependentBean : dependentBeans) {               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                  actualDependentBeans.add(dependentBean);               }            }            if (!actualDependentBeans.isEmpty()) {               throw new BeanCurrentlyInCreationException(beanName,                     "Bean with name '" + beanName + "' has been injected into other beans [" +                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +                     "] in its raw version as part of a circular reference, but has eventually been " +                     "wrapped. This means that said other beans do not use the final version of the " +                     "bean. This is often the result of over-eager type matching - consider using " +                     "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");            }         }      }   }   // Register bean as disposable.   try {      registerDisposableBeanIfNecessary(beanName, bean, mbd);   }   catch (BeanDefinitionValidationException ex) {      throw new BeanCreationException(            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);   }   return exposedObject;}

如果该bean没有任何依赖会很顺利的通过反射创立,调用如下办法。

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {   Assert.notNull(ctor, "Constructor must not be null");   try {      ReflectionUtils.makeAccessible(ctor);      if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {         return KotlinDelegate.instantiateClass(ctor, args);      }      else {         Class<?>[] parameterTypes = ctor.getParameterTypes();         Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");         Object[] argsWithDefaultValues = new Object[args.length];         for (int i = 0 ; i < args.length; i++) {            if (args[i] == null) {               Class<?> parameterType = parameterTypes[i];               argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);            }            else {               argsWithDefaultValues[i] = args[i];            }         }         return ctor.newInstance(argsWithDefaultValues);      }   }   ...略}

最初把创立好的bean,增加进map中

protected void addSingleton(String beanName, Object singletonObject) {   synchronized (this.singletonObjects) {      this.singletonObjects.put(beanName, singletonObject);      this.singletonFactories.remove(beanName);      this.earlySingletonObjects.remove(beanName);      this.registeredSingletons.add(beanName);   }}

依赖注入

依赖注入呢,会在创立实现后多一步

如果有bean,有须要依赖注入的属性

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {   if (pvs.isEmpty()) {      return;   }   if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {      ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());   }   MutablePropertyValues mpvs = null;   List<PropertyValue> original;   if (pvs instanceof MutablePropertyValues) {      mpvs = (MutablePropertyValues) pvs;      if (mpvs.isConverted()) {         // Shortcut: use the pre-converted values as-is.         try {            bw.setPropertyValues(mpvs);            return;         }         catch (BeansException ex) {            throw new BeanCreationException(                  mbd.getResourceDescription(), beanName, "Error setting property values", ex);         }      }      original = mpvs.getPropertyValueList();   }   else {      original = Arrays.asList(pvs.getPropertyValues());   }   TypeConverter converter = getCustomTypeConverter();   if (converter == null) {      converter = bw;   }   //BeanDefinitionValueResolver对BeanDefinition的解析是在这个valueResolver中实现   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);   // Create a deep copy, resolving any references for values.   List<PropertyValue> deepCopy = new ArrayList<>(original.size());   boolean resolveNecessary = false;   for (PropertyValue pv : original) {      if (pv.isConverted()) {         deepCopy.add(pv);      }      else {         String propertyName = pv.getName();         Object originalValue = pv.getValue();         if (originalValue == AutowiredPropertyMarker.INSTANCE) {            Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();            if (writeMethod == null) {               throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);            }            originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);         }         Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//获取到的bean对象         Object convertedValue = resolvedValue;         //判断是否有set办法         boolean convertible = bw.isWritableProperty(propertyName) &&               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);         if (convertible) {            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);         }         // Possibly store converted value in merged bean definition,         // in order to avoid re-conversion for every created bean instance.         if (resolvedValue == originalValue) {            if (convertible) {               pv.setConvertedValue(convertedValue);            }            deepCopy.add(pv);         }         else if (convertible && originalValue instanceof TypedStringValue &&               !((TypedStringValue) originalValue).isDynamic() &&               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {            pv.setConvertedValue(convertedValue);            deepCopy.add(pv);         }         else {            resolveNecessary = true;            deepCopy.add(new PropertyValue(pv, convertedValue));         }      }   }   if (mpvs != null && !resolveNecessary) {      mpvs.setConverted();   }   // Set our (possibly massaged) deep copy.   try {      //依赖注入产生的中央      bw.setPropertyValues(new MutablePropertyValues(deepCopy));   }   catch (BeansException ex) {      throw new BeanCreationException(            mbd.getResourceDescription(), beanName, "Error setting property values", ex);   }}

最终会调用set办法,进行注入

//set办法注入@Overridepublic void setValue(@Nullable Object value) throws Exception {   Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?         ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :         this.pd.getWriteMethod());   if (System.getSecurityManager() != null) {      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {         ReflectionUtils.makeAccessible(writeMethod);         return null;      });      try {         AccessController.doPrivileged((PrivilegedExceptionAction<Object>)               () -> writeMethod.invoke(getWrappedInstance(), value), acc);      }      catch (PrivilegedActionException ex) {         throw ex.getException();      }   }   else {      ReflectionUtils.makeAccessible(writeMethod);      writeMethod.invoke(getWrappedInstance(), value);   }}

@Autowired呢略微有点不同
它是在此处进行解决。

注解是通过field间接设置值AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject

@Overrideprotected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {   Field field = (Field) this.member;   Object value;   if (this.cached) {      try {         value = resolvedCachedArgument(beanName, this.cachedFieldValue);      }      catch (NoSuchBeanDefinitionException ex) {         // Unexpected removal of target bean for cached argument -> re-resolve         value = resolveFieldValue(field, bean, beanName);      }   }   else {      value = resolveFieldValue(field, bean, beanName);   }   if (value != null) {      ReflectionUtils.makeAccessible(field);      field.set(bean, value);   }}

循环依赖

测试代码如下

@Componentpublic class Father {   @Autowired   private Son son;   public void say(){      son.say();      System.out.println("say hello");   }}@Componentpublic class Son {   @Autowired   private Father father;   public void say(){      System.out.println("abcdefg");   }}

如何解决循环依赖呢?spring会在创立反射创立完bean之后,依赖注入之前,把bean的援用先缓存到singletonFactories

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {   Assert.notNull(singletonFactory, "Singleton factory must not be null");   synchronized (this.singletonObjects) {      if (!this.singletonObjects.containsKey(beanName)) {         this.singletonFactories.put(beanName, singletonFactory);         this.earlySingletonObjects.remove(beanName);         this.registeredSingletons.add(beanName);      }   }}

着有什么用呢

当解析类中的bean的时候会调用getBean获取,就会进入到DefaultSingletonBeanRegistry#getSingleton(String, boolean)尝试获取bean,这外面`
singletonsCurrentlyInCreation
会记录正在创立的bean,例如下面我写的例子,father须要son,son又须要father,不论哪一个先创立,举个例子,father先创立,在须要注入的时候,发现son没有创立,这个时候,开始创立son,son在注入的时候,又须要father,此时father还未创立完,这时候singletonFactories就起到作用了,singletonFactories存的是创立实现的,然而还注入实例的对象,然而father的援用不会变,只是还没有给son赋值。这时候就把father的援用先给son,son创立实现,在赋值给father。大抵就是这么一个过程。创立实现,再把singletonFactories外面的删除,对立贮存到singletonObjects`。

@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {   // Quick check for existing instance without full singleton lock|疾速检没有锁的现有实例   Object singletonObject = this.singletonObjects.get(beanName);   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {      singletonObject = this.earlySingletonObjects.get(beanName);      if (singletonObject == null && allowEarlyReference) {         synchronized (this.singletonObjects) {            // Consistent creation of early reference within full singleton lock|在残缺的单例锁中统一地创立晚期援用            singletonObject = this.singletonObjects.get(beanName);            if (singletonObject == null) {               singletonObject = this.earlySingletonObjects.get(beanName);               if (singletonObject == null) {                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);                  if (singletonFactory != null) {                     singletonObject = singletonFactory.getObject();                     this.earlySingletonObjects.put(beanName, singletonObject);                     this.singletonFactories.remove(beanName);                  }               }            }         }      }   }   return singletonObject;}

创立实现当前删除,对立存储到singletonObjects中。

protected void addSingleton(String beanName, Object singletonObject) {   synchronized (this.singletonObjects) {      this.singletonObjects.put(beanName, singletonObject);      this.singletonFactories.remove(beanName);      this.earlySingletonObjects.remove(beanName);      this.registeredSingletons.add(beanName);   }}