前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring IOC 源码解析(下)

Spring IOC 源码解析(下)

作者头像
黑洞代码
发布2021-01-14 15:36:41
3910
发布2021-01-14 15:36:41
举报
文章被收录于专栏:落叶飞翔的蜗牛

内含大量源码,建议横屏观看

接上一篇帖子:Spring IOC 源码解析(上)

实例化Bean

上一步创建了BeanFactory,并将BeanDefinition注册到了BeanFactory中的ConcurrentHashMap中了。并且以BeanName为key,BeanFactory为value。那么我们现在有了Bean定义,但还没有实例,也没有构建Bean之间的依赖关系。我们知道,构建依赖关系是 IOC 的一个重要的任务,我们怎么能放过。那么是在哪里做的呢?在 finishBeanFactoryInitialization(beanFactory) 方法中,方法定义如下:

AbstractApplicationContext

代码块

Java

代码语言:javascript
复制
/**
代码语言:javascript
复制
   * Finish the initialization of this context's bean factory,
代码语言:javascript
复制
   * initializing all remaining singleton beans.
代码语言:javascript
复制
   */
代码语言:javascript
复制
  protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
代码语言:javascript
复制
    // Initialize conversion service for this context.
代码语言:javascript
复制
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
代码语言:javascript
复制
        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
代码语言:javascript
复制
      beanFactory.setConversionService(
代码语言:javascript
复制
          beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    // Register a default embedded value resolver if no bean post-processor
代码语言:javascript
复制
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
代码语言:javascript
复制
    // at this point, primarily for resolution in annotation attribute values.
代码语言:javascript
复制
    if (!beanFactory.hasEmbeddedValueResolver()) {
代码语言:javascript
复制
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
代码语言:javascript
复制
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
代码语言:javascript
复制
    for (String weaverAwareName : weaverAwareNames) {
代码语言:javascript
复制
      getBean(weaverAwareName);
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    // Stop using the temporary ClassLoader for type matching.
代码语言:javascript
复制
    beanFactory.setTempClassLoader(null);
代码语言:javascript
复制
代码语言:javascript
复制
    // Allow for caching all bean definition metadata, not expecting further changes.
代码语言:javascript
复制
    beanFactory.freezeConfiguration();
代码语言:javascript
复制
代码语言:javascript
复制
    // Instantiate all remaining (non-lazy-init) singletons.
代码语言:javascript
复制
    beanFactory.preInstantiateSingletons();
代码语言:javascript
复制
  }

DefaultListableBeanFactory

该方法中重要的一步是 : beanFactory.preInstantiateSingletons(),我们有必要看看该方法实现:

代码块

Java

代码语言:javascript
复制
@Override
代码语言:javascript
复制
  public void preInstantiateSingletons() throws BeansException {
代码语言:javascript
复制
    if (logger.isDebugEnabled()) {
代码语言:javascript
复制
      logger.debug("Pre-instantiating singletons in " + this);
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
代码语言:javascript
复制
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
代码语言:javascript
复制
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
代码语言:javascript
复制
代码语言:javascript
复制
    // Trigger initialization of all non-lazy singleton beans...
代码语言:javascript
复制
    for (String beanName : beanNames) {
代码语言:javascript
复制
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
代码语言:javascript
复制
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
代码语言:javascript
复制
        if (isFactoryBean(beanName)) {
代码语言:javascript
复制
          Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
代码语言:javascript
复制
          if (bean instanceof FactoryBean) {
代码语言:javascript
复制
            final FactoryBean<?> factory = (FactoryBean<?>) bean;
代码语言:javascript
复制
            boolean isEagerInit;
代码语言:javascript
复制
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
代码语言:javascript
复制
              isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
代码语言:javascript
复制
                      ((SmartFactoryBean<?>) factory)::isEagerInit,
代码语言:javascript
复制
                  getAccessControlContext());
代码语言:javascript
复制
            }
代码语言:javascript
复制
            else {
代码语言:javascript
复制
              isEagerInit = (factory instanceof SmartFactoryBean &&
代码语言:javascript
复制
                  ((SmartFactoryBean<?>) factory).isEagerInit());
代码语言:javascript
复制
            }
代码语言:javascript
复制
            if (isEagerInit) {
代码语言:javascript
复制
              getBean(beanName);
代码语言:javascript
复制
            }
代码语言:javascript
复制
          }
代码语言:javascript
复制
        }
代码语言:javascript
复制
        else {
代码语言:javascript
复制
          getBean(beanName);
代码语言:javascript
复制
        }
代码语言:javascript
复制
      }
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    // Trigger post-initialization callback for all applicable beans...
代码语言:javascript
复制
    for (String beanName : beanNames) {
代码语言:javascript
复制
      Object singletonInstance = getSingleton(beanName);
代码语言:javascript
复制
      if (singletonInstance instanceof SmartInitializingSingleton) {
代码语言:javascript
复制
        final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
代码语言:javascript
复制
        if (System.getSecurityManager() != null) {
代码语言:javascript
复制
          AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
代码语言:javascript
复制
            smartSingleton.afterSingletonsInstantiated();
代码语言:javascript
复制
            return null;
代码语言:javascript
复制
          }, getAccessControlContext());
代码语言:javascript
复制
        }
代码语言:javascript
复制
        else {
代码语言:javascript
复制
          smartSingleton.afterSingletonsInstantiated();
代码语言:javascript
复制
        }
代码语言:javascript
复制
      }
代码语言:javascript
复制
    }
代码语言:javascript
复制
  }

该方法首先循环所有的BeanNames,并且调用getBean(beanName)方法,该方法实际上就是创建bean并递归构建依赖关系。getBean(beanName)方法最终会调用 doGetBean(name, null, null, false),我们进入该方法查看

/**

* Return an instance, which may be shared or independent, of the specified bean.

* @param name the name of the bean to retrieve

* @param requiredType the required type of the bean to retrieve

* @param args arguments to use when creating a bean instance using explicit arguments

* (only applied when creating a new instance as opposed to retrieving an existing one)

* @param typeCheckOnly whether the instance is obtained for a type check,

* not for actual use

* @return an instance of the bean

* @throws BeansException if the bean could not be created

*/

@SuppressWarnings("unchecked")

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,

@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

final 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.isDebugEnabled()) {

if (isSingletonCurrentlyInCreation(beanName)) {

logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +

"' that is not fully initialized yet - a consequence of a circular reference");

}

else {

logger.debug("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 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);

}

else if (args != null) {

// Delegation to parent with explicit args.

return (T) parentBeanFactory.getBean(nameToLookup, args);

}

else {

// No args -> delegate to standard getBean method.

return parentBeanFactory.getBean(nameToLookup, requiredType);

}

}

if (!typeCheckOnly) {

markBeanAsCreated(beanName);

}

try {

final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.

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()) {

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;

}

});

bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

}

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();

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.isDebugEnabled()) {

logger.debug("Failed to convert bean '" + name + "' to required type '" +

ClassUtils.getQualifiedName(requiredType) + "'", ex);

}

throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());

}

}

return (T) bean;

}

这个方法很长,只选部分源码进行分析:

代码块

Java

代码语言:javascript
复制
// Guarantee initialization of beans that the current bean depends on.
代码语言:javascript
复制
        String[] dependsOn = mbd.getDependsOn();
代码语言:javascript
复制
        if (dependsOn != null) {
代码语言:javascript
复制
          for (String dep : dependsOn) {
代码语言:javascript
复制
            if (isDependent(beanName, dep)) {
代码语言:javascript
复制
              throw new BeanCreationException(mbd.getResourceDescription(), beanName,
代码语言:javascript
复制
                  "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
代码语言:javascript
复制
            }
代码语言:javascript
复制
            registerDependentBean(dep, beanName);
代码语言:javascript
复制
            try {
代码语言:javascript
复制
              getBean(dep);
代码语言:javascript
复制
            }
代码语言:javascript
复制
            catch (NoSuchBeanDefinitionException ex) {
代码语言:javascript
复制
              throw new BeanCreationException(mbd.getResourceDescription(), beanName,
代码语言:javascript
复制
                  "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
代码语言:javascript
复制
            }
代码语言:javascript
复制
          }
代码语言:javascript
复制
        }
代码语言:javascript
复制
代码语言:javascript
复制
        // Create bean instance.
代码语言:javascript
复制
        if (mbd.isSingleton()) {
代码语言:javascript
复制
          sharedInstance = getSingleton(beanName, () -> {
代码语言:javascript
复制
            try {
代码语言:javascript
复制
              return createBean(beanName, mbd, args);
代码语言:javascript
复制
            }
代码语言:javascript
复制
            catch (BeansException ex) {
代码语言:javascript
复制
              // Explicitly remove instance from singleton cache: It might have been put there
代码语言:javascript
复制
              // eagerly by the creation process, to allow for circular reference resolution.
代码语言:javascript
复制
              // Also remove any beans that received a temporary reference to the bean.
代码语言:javascript
复制
              destroySingleton(beanName);
代码语言:javascript
复制
              throw ex;
代码语言:javascript
复制
            }
代码语言:javascript
复制
          });
代码语言:javascript
复制
          bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
代码语言:javascript
复制
        }

可以看到,该方法首先会获取依赖关系mbd.getDependsOn();,拿着依赖的BeanName 递归调用 getBean方法,直到调用 getSingleton 方法返回依赖bean,而 getSingleton 方法的参数是 createBean() 方法返回的实例。createBean()是在AbstractAutowireCapableBeanFactory中实现的。

AbstractAutowireCapableBeanFactory

createBean方法实现:

代码块

Java

代码语言:javascript
复制
/**
代码语言:javascript
复制
   * Central method of this class: creates a bean instance,
代码语言:javascript
复制
   * populates the bean instance, applies post-processors, etc.
代码语言:javascript
复制
   * @see #doCreateBean
代码语言:javascript
复制
   */
代码语言:javascript
复制
  @Override
代码语言:javascript
复制
  protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
代码语言:javascript
复制
      throws BeanCreationException {
代码语言:javascript
复制
代码语言:javascript
复制
    if (logger.isDebugEnabled()) {
代码语言:javascript
复制
      logger.debug("Creating instance of bean '" + beanName + "'");
代码语言:javascript
复制
    }
代码语言:javascript
复制
    RootBeanDefinition mbdToUse = mbd;
代码语言:javascript
复制
代码语言:javascript
复制
    // Make sure bean class is actually resolved at this point, and
代码语言:javascript
复制
    // clone the bean definition in case of a dynamically resolved Class
代码语言:javascript
复制
    // which cannot be stored in the shared merged bean definition.
代码语言:javascript
复制
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
代码语言:javascript
复制
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
代码语言:javascript
复制
      mbdToUse = new RootBeanDefinition(mbd);
代码语言:javascript
复制
      mbdToUse.setBeanClass(resolvedClass);
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    // Prepare method overrides.
代码语言:javascript
复制
    try {
代码语言:javascript
复制
      mbdToUse.prepareMethodOverrides();
代码语言:javascript
复制
    }
代码语言:javascript
复制
    catch (BeanDefinitionValidationException ex) {
代码语言:javascript
复制
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
代码语言:javascript
复制
          beanName, "Validation of method overrides failed", ex);
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    try {
代码语言:javascript
复制
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
代码语言:javascript
复制
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
代码语言:javascript
复制
      if (bean != null) {
代码语言:javascript
复制
        return bean;
代码语言:javascript
复制
      }
代码语言:javascript
复制
    }
代码语言:javascript
复制
    catch (Throwable ex) {
代码语言:javascript
复制
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
代码语言:javascript
复制
          "BeanPostProcessor before instantiation of bean failed", ex);
代码语言:javascript
复制
    }
代码语言:javascript
复制
代码语言:javascript
复制
    try {
代码语言:javascript
复制
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
代码语言:javascript
复制
      if (logger.isDebugEnabled()) {
代码语言:javascript
复制
        logger.debug("Finished creating instance of bean '" + beanName + "'");
代码语言:javascript
复制
      }
代码语言:javascript
复制
      return beanInstance;
代码语言:javascript
复制
    }
代码语言:javascript
复制
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
代码语言:javascript
复制
      // A previously detected exception with proper bean creation context already,
代码语言:javascript
复制
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
代码语言:javascript
复制
      throw ex;
代码语言:javascript
复制
    }
代码语言:javascript
复制
    catch (Throwable ex) {
代码语言:javascript
复制
      throw new BeanCreationException(
代码语言:javascript
复制
          mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
代码语言:javascript
复制
    }
代码语言:javascript
复制
  }
从createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法的实现可以看出,该方法内部调用 doCreateBean 方法,doCreateBean方法的实现如下:

/**

* Actually create the specified bean. Pre-creation processing has already happened

* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.

* <p>Differentiates between default bean instantiation, use of a

* factory method, and autowiring a constructor.

* @param beanName the name of the bean

* @param mbd the merged bean definition for the bean

* @param args explicit arguments to use for constructor or factory method invocation

* @return a new instance of the bean

* @throws BeanCreationException if the bean could not be created

* @see #instantiateBean

* @see #instantiateUsingFactoryMethod

* @see #autowireConstructor

*/

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

throws BeanCreationException {

// Instantiate the bean.

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

final 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.isDebugEnabled()) {

logger.debug("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 " +

"'getBeanNamesOfType' 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;

}

这个方法很长,只挑选重要的两行代码讲解:

  1. instanceWrapper = createBeanInstance(beanName, mbd, args) 创建实例。
  2. populateBean(beanName, mbd, instanceWrapper) , 该方法用于填充Bean,该方法可以就是说就是发生依赖注入的地方。

createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 方法实现如下:

/**

* Create a new instance for the specified bean, using an appropriate instantiation strategy:

* factory method, constructor autowiring, or simple instantiation.

* @param beanName the name of the bean

* @param mbd the bean definition for the bean

* @param args explicit arguments to use for constructor or factory method invocation

* @return a BeanWrapper for the new instance

* @see #obtainFromSupplier

* @see #instantiateUsingFactoryMethod

* @see #autowireConstructor

* @see #instantiateBean

*/

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

// Make sure bean class is actually resolved at this point.

Class<?> beanClass = resolveBeanClass(mbd, beanName);

if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,

"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());

}

Supplier<?> instanceSupplier = mbd.getInstanceSupplier();

if (instanceSupplier != null) {

return obtainFromSupplier(instanceSupplier, beanName);

}

if (mbd.getFactoryMethodName() != null) {

return instantiateUsingFactoryMethod(beanName, mbd, args);

}

// Shortcut when re-creating the same bean...

boolean resolved = false;

boolean autowireNecessary = false;

if (args == null) {

synchronized (mbd.constructorArgumentLock) {

if (mbd.resolvedConstructorOrFactoryMethod != null) {

resolved = true;

autowireNecessary = mbd.constructorArgumentsResolved;

}

}

}

if (resolved) {

if (autowireNecessary) {

return autowireConstructor(beanName, mbd, null, null);

}

else {

return instantiateBean(beanName, mbd);

}

}

// Need to determine the constructor...

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

if (ctors != null ||

mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||

mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {

return autowireConstructor(beanName, mbd, ctors, args);

}

// No special handling: simply use no-arg constructor.

return instantiateBean(beanName, mbd);

}

看最后一行代码,调用 instantiateBean(beanName, mbd) 方法,我们看看这个方法实现:

/**

* Instantiate the given bean using its default constructor.

* @param beanName the name of the bean

* @param mbd the bean definition for the bean

* @return a BeanWrapper for the new instance

*/

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {

try {

Object beanInstance;

final BeanFactory parent = this;

if (System.getSecurityManager() != null) {

beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->

getInstantiationStrategy().instantiate(mbd, beanName, parent),

getAccessControlContext());

}

else {

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

}

BeanWrapper bw = new BeanWrapperImpl(beanInstance);

initBeanWrapper(bw);

return bw;

}

catch (Throwable ex) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);

}

}

instantiateBean(final String beanName, final RootBeanDefinition mbd)方法核心逻辑是 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent),携带BeanName ,RootBeanDefinition ,发挥的策略对象是 SimpleInstantiationStrategy,该方法内部调用静态方法 BeanUtils.instantiateClass(constructorToUse),这个方法的实现如下:

/**

* Convenience method to instantiate a class using the given constructor.

* <p>Note that this method tries to set the constructor accessible if given a

* non-accessible (that is, non-public) constructor, and supports Kotlin classes

* with optional parameters and default values.

* @param ctor the constructor to instantiate

* @param args the constructor arguments to apply (use {@code null} for an unspecified

* parameter if needed for Kotlin classes with optional parameters and default values)

* @return the new instance

* @throws BeanInstantiationException if the bean cannot be instantiated

* @see Constructor#newInstance

*/

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {

Assert.notNull(ctor, "Constructor must not be null");

try {

ReflectionUtils.makeAccessible(ctor);

return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?

KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));

}

catch (InstantiationException ex) {

throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);

}

catch (IllegalAccessException ex) {

throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);

}

catch (IllegalArgumentException ex) {

throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);

}

catch (InvocationTargetException ex) {

throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());

}

}

然后调用 Constructor 的 newInstance 方法, 也就是最终使用反射创建了该实例。PS:该方法会判断是否是 Kotlin 类型。如果不是,则调用构造器的实例方法。

到这里,我们的实例已经创建。但是我们的实例的依赖还没有设置,刚刚我们在 doCreateBean 方法说关心的第2行代码:

populateBean(beanName, mbd, instanceWrapper) , 该方法用于填充Bean,该方法可以就是说就是发生依赖注入的地方。还是会到AbstractAutowireCapableBeanFactory类中看下populateBean()方法的实现。

AbstractAutowireCapableBeanFactory

/**

* Populate the bean instance in the given BeanWrapper with the property values

* from the bean definition.

* @param beanName the name of the bean

* @param mbd the bean definition for the bean

* @param bw the BeanWrapper with bean instance

*/

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

if (bw == null) {

if (mbd.hasPropertyValues()) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");

}

else {

// Skip property population phase for null instance.

return;

}

}

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the

// state of the bean before properties are set. This can be used, for example,

// to support styles of field injection.

boolean continueWithPropertyPopulation = true;

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

continueWithPropertyPopulation = false;

break;

}

}

}

}

if (!continueWithPropertyPopulation) {

return;

}

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||

mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

// Add property values based on autowire by name if applicable.

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {

autowireByName(beanName, mbd, bw, newPvs);

}

// Add property values based on autowire by type if applicable.

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {

autowireByType(beanName, mbd, bw, newPvs);

}

pvs = newPvs;

}

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

if (hasInstAwareBpps || needsDepCheck) {

if (pvs == null) {

pvs = mbd.getPropertyValues();

}

PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

if (hasInstAwareBpps) {

for (BeanPostProcessor bp : getBeanPostProcessors()) {

if (bp instanceof InstantiationAwareBeanPostProcessor) {

InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

if (pvs == null) {

return;

}

}

}

}

if (needsDepCheck) {

checkDependencies(beanName, mbd, filteredPds, pvs);

}

}

if (pvs != null) {

applyPropertyValues(beanName, mbd, bw, pvs);

}

}

整个方法的核心逻辑是PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);这一行代码。即获取该bean的所有属性,也就是我们配置property元素。最后执行 applyPropertyValues(beanName, mbd, bw, pvs) 方法。applyPropertyValues方法的实现如下:

/**

* Apply the given property values, resolving any runtime references

* to other beans in this bean factory. Must use deep copy, so we

* don't permanently modify this property.

* @param beanName the bean name passed for better exception information

* @param mbd the merged bean definition

* @param bw the BeanWrapper wrapping the target object

* @param pvs the new property values

*/

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 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();

Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);

Object convertedValue = resolvedValue;

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);

}

}

关键代码Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);该方法是获取property对应的值。看到具体调用方法BeanDefinitionValueResolver.resolveValueIfNecessary实现如下:

/**

* Given a PropertyValue, return a value, resolving any references to other

* beans in the factory if necessary. The value could be:

* <li>A BeanDefinition, which leads to the creation of a corresponding

* new bean instance. Singleton flags and names of such "inner beans"

* are always ignored: Inner beans are anonymous prototypes.

* <li>A RuntimeBeanReference, which must be resolved.

* <li>A ManagedList. This is a special collection that may contain

* RuntimeBeanReferences or Collections that will need to be resolved.

* <li>A ManagedSet. May also contain RuntimeBeanReferences or

* Collections that will need to be resolved.

* <li>A ManagedMap. In this case the value may be a RuntimeBeanReference

* or Collection that will need to be resolved.

* <li>An ordinary object or {@code null}, in which case it's left alone.

* @param argName the name of the argument that the value is defined for

* @param value the value object to resolve

* @return the resolved object

*/

@Nullable

public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {

// We must check each value to see whether it requires a runtime reference

// to another bean to be resolved.

if (value instanceof RuntimeBeanReference) {

RuntimeBeanReference ref = (RuntimeBeanReference) value;

return resolveReference(argName, ref);

}

else if (value instanceof RuntimeBeanNameReference) {

String refName = ((RuntimeBeanNameReference) value).getBeanName();

refName = String.valueOf(doEvaluate(refName));

if (!this.beanFactory.containsBean(refName)) {

throw new BeanDefinitionStoreException(

"Invalid bean name '" + refName + "' in bean reference for " + argName);

}

return refName;

}

else if (value instanceof BeanDefinitionHolder) {

// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.

BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;

return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());

}

else if (value instanceof BeanDefinition) {

// Resolve plain BeanDefinition, without contained name: use dummy name.

BeanDefinition bd = (BeanDefinition) value;

String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +

ObjectUtils.getIdentityHexString(bd);

return resolveInnerBean(argName, innerBeanName, bd);

}

else if (value instanceof ManagedArray) {

// May need to resolve contained runtime references.

ManagedArray array = (ManagedArray) value;

Class<?> elementType = array.resolvedElementType;

if (elementType == null) {

String elementTypeName = array.getElementTypeName();

if (StringUtils.hasText(elementTypeName)) {

try {

elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());

array.resolvedElementType = elementType;

}

catch (Throwable ex) {

// Improve the message by showing the context.

throw new BeanCreationException(

this.beanDefinition.getResourceDescription(), this.beanName,

"Error resolving array type for " + argName, ex);

}

}

else {

elementType = Object.class;

}

}

return resolveManagedArray(argName, (List<?>) value, elementType);

}

else if (value instanceof ManagedList) {

// May need to resolve contained runtime references.

return resolveManagedList(argName, (List<?>) value);

}

else if (value instanceof ManagedSet) {

// May need to resolve contained runtime references.

return resolveManagedSet(argName, (Set<?>) value);

}

else if (value instanceof ManagedMap) {

// May need to resolve contained runtime references.

return resolveManagedMap(argName, (Map<?, ?>) value);

}

else if (value instanceof ManagedProperties) {

Properties original = (Properties) value;

Properties copy = new Properties();

original.forEach((propKey, propValue) -> {

if (propKey instanceof TypedStringValue) {

propKey = evaluate((TypedStringValue) propKey);

}

if (propValue instanceof TypedStringValue) {

propValue = evaluate((TypedStringValue) propValue);

}

if (propKey == null || propValue == null) {

throw new BeanCreationException(

this.beanDefinition.getResourceDescription(), this.beanName,

"Error converting Properties key/value pair for " + argName + ": resolved to null");

}

copy.put(propKey, propValue);

});

return copy;

}

else if (value instanceof TypedStringValue) {

// Convert value to target type here.

TypedStringValue typedStringValue = (TypedStringValue) value;

Object valueObject = evaluate(typedStringValue);

try {

Class<?> resolvedTargetType = resolveTargetType(typedStringValue);

if (resolvedTargetType != null) {

return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);

}

else {

return valueObject;

}

}

catch (Throwable ex) {

// Improve the message by showing the context.

throw new BeanCreationException(

this.beanDefinition.getResourceDescription(), this.beanName,

"Error converting typed String value for " + argName, ex);

}

}

else if (value instanceof NullBean) {

return null;

}

else {

return evaluate(value);

}

}

核心方法:resolveReference(argName, ref);看看这个方法的实现:

/**

* Resolve a reference to another bean in the factory.

*/

@Nullable

private Object resolveReference(Object argName, RuntimeBeanReference ref) {

try {

Object bean;

String refName = ref.getBeanName();

refName = String.valueOf(doEvaluate(refName));

if (ref.isToParent()) {

if (this.beanFactory.getParentBeanFactory() == null) {

throw new BeanCreationException(

this.beanDefinition.getResourceDescription(), this.beanName,

"Can't resolve reference to bean '" + refName +

"' in parent factory: no parent factory available");

}

bean = this.beanFactory.getParentBeanFactory().getBean(refName);

}

else {

bean = this.beanFactory.getBean(refName);

this.beanFactory.registerDependentBean(refName, this.beanName);

}

if (bean instanceof NullBean) {

bean = null;

}

return bean;

}

catch (BeansException ex) {

throw new BeanCreationException(

this.beanDefinition.getResourceDescription(), this.beanName,

"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);

}

}

其中有一行熟悉的代码:bean = this.beanFactory.getBean(refName),对,这里就是发生递归的地方。该方法会拿着属性名称从容器中获取实例。通过以上操作就找到了Bean依赖的Bean。

我们回到 AbstractAutowireCapableBeanFactory.applyPropertyValues 方法。此时deepCopy 集合已经有值了。然后看到bw.setPropertyValues(new MutablePropertyValues(deepCopy));这行代码,该方法会调用 AbstractPropertyAccessor.setPropertyValues 方法完成注入

@Override

public void setPropertyValues(PropertyValues pvs) throws BeansException {

setPropertyValues(pvs, false, false);

}

最终调用的方法是AbstractPropertyAccessor.setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)

AbstractPropertyAccessor

@Override

public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)

throws BeansException {

List<PropertyAccessException> propertyAccessExceptions = null;

List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?

((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));

for (PropertyValue pv : propertyValues) {

try {

// This method may throw any BeansException, which won't be caught

// here, if there is a critical failure such as no matching field.

// We can attempt to deal only with less serious exceptions.

setPropertyValue(pv);

}

catch (NotWritablePropertyException ex) {

if (!ignoreUnknown) {

throw ex;

}

// Otherwise, just ignore it and continue...

}

catch (NullValueInNestedPathException ex) {

if (!ignoreInvalid) {

throw ex;

}

// Otherwise, just ignore it and continue...

}

catch (PropertyAccessException ex) {

if (propertyAccessExceptions == null) {

propertyAccessExceptions = new ArrayList<>();

}

propertyAccessExceptions.add(ex);

}

}

// If we encountered individual exceptions, throw the composite exception.

if (propertyAccessExceptions != null) {

PropertyAccessException[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[0]);

throw new PropertyBatchUpdateException(paeArray);

}

}

该方法会循环元素列表, 循环中调用 setPropertyValue(PropertyValue pv) 方法, 该方法最后会调用 nestedPa.setPropertyValue(tokens, pv) 方法

@Override

public void setPropertyValue(PropertyValue pv) throws BeansException {

setPropertyValue(pv.getName(), pv.getValue());

}

setPropertyValue最终实现是在AbstractNestablePropertyAccessor中:

AbstractNestablePropertyAccessor

@Override

public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {

AbstractNestablePropertyAccessor nestedPa;

try {

nestedPa = getPropertyAccessorForPropertyPath(propertyName);

}

catch (NotReadablePropertyException ex) {

throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,

"Nested property in path '" + propertyName + "' does not exist", ex);

}

PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));

nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));

}

最后一行代码nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));看下方法实现:

protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {

if (tokens.keys != null) {

processKeyedProperty(tokens, pv);

}

else {

processLocalProperty(tokens, pv);

}

}

看最后一行代码processLocalProperty(tokens, pv);方法的实现:

private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {

PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);

if (ph == null || !ph.isWritable()) {

if (pv.isOptional()) {

if (logger.isDebugEnabled()) {

logger.debug("Ignoring optional value for property '" + tokens.actualName +

"' - property not found on bean class [" + getRootClass().getName() + "]");

}

return;

}

else {

throw createNotWritablePropertyException(tokens.canonicalName);

}

}

Object oldValue = null;

try {

Object originalValue = pv.getValue();

Object valueToApply = originalValue;

if (!Boolean.FALSE.equals(pv.conversionNecessary)) {

if (pv.isConverted()) {

valueToApply = pv.getConvertedValue();

}

else {

if (isExtractOldValueForEditor() && ph.isReadable()) {

try {

oldValue = ph.getValue();

}

catch (Exception ex) {

if (ex instanceof PrivilegedActionException) {

ex = ((PrivilegedActionException) ex).getException();

}

if (logger.isDebugEnabled()) {

logger.debug("Could not read previous value of property '" +

this.nestedPath + tokens.canonicalName + "'", ex);

}

}

}

valueToApply = convertForProperty(

tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());

}

pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);

}

ph.setValue(valueToApply);

}

catch (TypeMismatchException ex) {

throw ex;

}

catch (InvocationTargetException ex) {

PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(

getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());

if (ex.getTargetException() instanceof ClassCastException) {

throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());

}

else {

Throwable cause = ex.getTargetException();

if (cause instanceof UndeclaredThrowableException) {

// May happen e.g. with Groovy-generated methods

cause = cause.getCause();

}

throw new MethodInvocationException(propertyChangeEvent, cause);

}

}

catch (Exception ex) {

PropertyChangeEvent pce = new PropertyChangeEvent(

getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());

throw new MethodInvocationException(pce, ex);

}

}

该方法最后又会调用 ph.setValue(valueToApply) 方法,也就是BeanWrapperImpl.setValue() 方法,终于,我们要看到反射了,看到反射说明到了尽头。

@Override

public void setValue(final @Nullable Object value) throws Exception {

final 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);

}

}

该方法是最后一步,我们看到该方法会找的set方法,然后调用 Method 的 invoke 方法,完成属性注入。

我们从源码层面剖析 IOC 的初始化过程,也了解了 IOC 的底层原理实现, 我们总结一下: Spring 的 Bean 其实在内存状态就是 BeanDefinition, 在 Bean 的创建和依赖注入的过程中, 需要根据 BeanDefinition 的信息来递归的完成依赖注入, 从我们分析的代码可以看到,这些递归都是以 getBean() 为入口的, 一个递归是在上下文体系中查找需要的 Bean 和创建 Bean 的递归调用, 另一个 Bean 实在依赖注入时,通过递归调用容器的 getBean 方法, 得到当前的依赖 Bean, 同时也触发对依赖 Bean 的创建和注入. 在对 Bean 的属性进行依赖注入时, 解析的过程也是一个递归的过程, 这样, 根据依赖关系, 一层一层的完成 Bean 的创建和注入, 知道最后完成当前 Bean 的创建, 有了这个顶层 Bean 的创建和对他的属性依赖注入的完成, 意味着当前 Bean 相关的整个依赖链的注入也完成了.

总结一下 IOC 的初始化过程吧:

  1. 资源(Resource)定位;
  2. BeanDefinition 的载入和 BeanFactory 的构造.
  3. 想 IOC 容器(BeanFactory)注册 BeanDefinition.
  4. 根据 lazy-init 属性初始化 Bean 实例和依赖注入.
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接上一篇帖子:Spring IOC 源码解析(上)
  • 实例化Bean
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档