spring-BeanFactory

今天来看看BeanFactory

  • 子接口都有哪些? 职责分别是哪些?

  • getBean 方法?Bean是怎么加载进来的?

  • BeanDefined的创建过程 ?BeanDefined的理解?

  • 容器启动流程?

基础容器接口

image-20191205215235310

IOC时序图

image-20200125105144265

DI 时序图

![image-20200125104717425](/Users/zhengyumin/Library/Application Support/typora-user-images/image-20200125104717425.png)

子接口

HierarchicalBeanFactory

新增继承关系的容器

public interface HierarchicalBeanFactory extends BeanFactory {

   /**
    * Return the parent bean factory, or {@code null} if there is none.
    */
   @Nullable
   BeanFactory getParentBeanFactory();

   /**
    * Return whether the local bean factory contains a bean of the given name,
    * ignoring beans defined in ancestor contexts.
    * <p>This is an alternative to {@code containsBean}, ignoring a bean
    * of the given name from an ancestor bean factory.
    * @param name the name of the bean to query
    * @return whether a bean with the given name is defined in the local factory
    * @see BeanFactory#containsBean
    */
   boolean containsLocalBean(String name);

}

ListableBeanFactory

扩展BeanFactory接口,提供所有bean 实例的枚举,不再需要客户端通过一个个bean name查找.BeanFactory实现类预加载bean定义(如通过实现xml的工厂)需要实现这个接口.

如果一样实现了HierarchicalBeanFactory,返回值不会考虑父类BeanFactory,只考虑当前factory定义的类.当然也可以使用BeanFactoryUtils辅助类来查找祖先工厂中的类.

这个接口中的方法只会考虑本factory定义的bean.这些方法会忽略ConfigurableBeanFactory的registerSingleton注册的单例bean,getBeanNamesOfType和getBeansOfType是例外,一样会考虑手动注册的单例.当然BeanFactory的getBean一样可以透明访问这些特殊bean.当然在典型情况下,所有的bean都是由external bean定义,所以应用不需要顾虑这些差别.

注意:getBeanDefinitionCount和containsBeanDefinition的实现方法因为效率比较低,并不是供频繁调用的.

来源: https://docs.spring.io/spring-framework/docs/5.2.1.RELEASE/javadoc-api/org/springframework/beans/factory/ListableBeanFactory.html

public interface ListableBeanFactory extends BeanFactory {
   boolean containsBeanDefinition(String beanName);
   int getBeanDefinitionCount();
   String[] getBeanDefinitionNames();
   String[] getBeanNamesForType(ResolvableType type);
   String[] getBeanNamesForType(@Nullable Class<?> type);
   String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
   <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
   <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
         throws BeansException;
   String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
   Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
   @Nullable
   <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
         throws NoSuchBeanDefinitionException;
}

AutowireCapableBeanFactory

新增了生命周期的管理、依赖能力, 其他框架的集成代码可以利用此接口来连接和填充Spring无法控制其生命周期的现有bean实例。

https://docs.spring.io/spring-framework/docs/5.2.1.RELEASE/javadoc-api/org/springframework/beans/factory/config/AutowireCapableBeanFactory.html

public interface AutowireCapableBeanFactory extends BeanFactory {
    <T> T createBean(Class<T> beanClass) throws BeansException;
    void autowireBean(Object existingBean) throws BeansException;
    Object configureBean(Object existingBean, String beanName) throws BeansException;
    Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
    Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
    void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
            throws BeansException;
    void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
    Object initializeBean(Object existingBean, String beanName) throws BeansException;
    Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException;
    Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException;
    void destroyBean(Object existingBean);
    <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
    Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;
    Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
            Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}

ConfigurableBeanFactory

主要用于配置 BeanFactory,(scope、classLoader、beanPostProcess) 这个接口里面定义的方法通常都是供框架内部使用的, 不适用于通常的应用程序, 源码如下

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,
                                                 SingletonBeanRegistry {
    String SCOPE_SINGLETON = "singleton";
    String SCOPE_PROTOTYPE = "prototype";

    void setParentBeanFactory(BeanFactory parentBeanFactory)
      throws IllegalStateException;

    // 设置 ClassLoader 的方法, 通常使用 setBeanClassLoader
    void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
    ClassLoader getBeanClassLoader();
    void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
    ClassLoader getTempClassLoader();

    // 是否缓存 bean 的源数据, 默认为 true
    void setCacheBeanMetadata(boolean cacheBeanMetadata);
    boolean isCacheBeanMetadata();

    // 设置 SPEL 表达式解析器
    void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
    BeanExpressionResolver getBeanExpressionResolver();

    void setConversionService(@Nullable ConversionService conversionService);
    ConversionService getConversionService();

    // 设置属性编辑器
    void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
    void registerCustomEditor(Class<?> requiredType,
                              Class<? extends PropertyEditor> propertyEditorClass);
    void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

    // 设置类型转换器
    void setTypeConverter(TypeConverter typeConverter);
    TypeConverter getTypeConverter();

    void addEmbeddedValueResolver(StringValueResolver valueResolver);
    boolean hasEmbeddedValueResolver();
    String resolveEmbeddedValue(String value);

    // 设置 bean 后置处理器
    void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
    int getBeanPostProcessorCount();

    // 注册 scope
    void registerScope(String scopeName, Scope scope);
    String[] getRegisteredScopeNames();
    Scope getRegisteredScope(String scopeName);

    AccessControlContext getAccessControlContext();

    void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

    // 为 bean 设置添加别名
    void registerAlias(String beanName, String alias)
      throws BeanDefinitionStoreException;
    void resolveAliases(StringValueResolver valueResolver);

    BeanDefinition getMergedBeanDefinition(String beanName)
      throws NoSuchBeanDefinitionException;

    boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

    void setCurrentlyInCreation(String beanName, boolean inCreation);
    boolean isCurrentlyInCreation(String beanName);

    void registerDependentBean(String beanName, String dependentBeanName);
    String[] getDependentBeans(String beanName);
    String[] getDependenciesForBean(String beanName);

    void destroyBean(String beanName, Object beanInstance);
    void destroyScopedBean(String beanName);
    void destroySingletons();
}

ConfigurableListableBeanFactory

​ 大多数可列出的bean工厂都将实现配置接口。 除了ConfigurableBeanFactory,它还提供了用于分析和修改Bean定义以及预先实例化单例的工具。
​ BeanFactory的此子接口不能在常规应用程序代码中使用:在典型使用情况下,请坚持使用BeanFactory或ListableBeanFactory。 即使需要访问bean工厂配置方法,该接口也仅允许框架内部即插即用。

注意: ApplicationContext中使用的就是ConfigurableListableBeanFactory

public interface ConfigurableListableBeanFactory
      extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
        void ignoreDependencyType(Class<?> type);	
        void ignoreDependencyInterface(Class<?> ifc);	
        void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
        boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
            throws NoSuchBeanDefinitionException;
        Iterator<String> getBeanNamesIterator();
        BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
        void clearMetadataCache();
        void freezeConfiguration();
        boolean isConfigurationFrozen();
        void preInstantiateSingletons() throws BeansException;
}

默认实现

DefaultListableBeanFactory

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
      implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
  ...
}

直接分析源码, 没什么目标会很迷茫

所以我们带着各种问题来看看spring的源码

  • spring是怎么解决循环依赖问题?

  • getBean 方法?Bean是怎么加载进来的?

  • BeanDefined的创建过程 ?BeanDefined的理解?

  • 容器启动流程?

先来看看继承体系

image-20191205172006709

对以上类简单介绍下:

FactoryBeanRegistrySupport 支持了类实例、别名、FactoryBean的注册、循环依赖的解决

*BeanFactory : 实现各种BeanFactory接口

BeanDefinitionRegistry :BeanDefintion注册

DefaultSingletonBeanRegistry

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/** Set of registered singletons, containing the bean names in registration order. */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

/** Names of beans that are currently in creation. */
private final Set<String> singletonsCurrentlyInCreation =
      Collections.newSetFromMap(new ConcurrentHashMap<>(16));

/** Names of beans currently excluded from in creation checks. */
private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}

(仔细看看上面各种类型,spring是怎么处理并发问题的)

这里是3个map用于存放singleton bean

  • singletonObjects :存放已经初始化完成的beanName 和bean的映射缓存(注意线程安全)
  • earlySingletonObjects : 提前暴露的beanName 和bean的映射缓存
  • singletonFactories: 存放beanName 和ObjectFactory的映射缓存

同时三个set

  • registeredSingletons :用于存放已经注册的bean
  • singletonsCurrentlyInCreation: 当前正在创建的bean
  • inCreationCheckExclusions : 不需要检查是否正常创建中的bean

而我们的关键是看看earlySingletonObjects这个map

什么样的对象可以放进去?

什么时候放进去?

(另外: 为什么需要singletonFactories?)

earlySingletonObjects

–>先看看earlySingletonObjects 是什么时候put对象进去的

/**
 * 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
 */
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   //是否在一级缓存中,有的话直接返回
   Object singletonObject = this.singletonObjects.get(beanName);
  //如果不在缓存中,并且正在创建中(什么时候放进去?)
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
     //锁住singletonObjects ,解决循环依赖中等待的问题
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
            //不在二级缓存中,并且允许提前初始化引用
         if (singletonObject == null && allowEarlyReference) {
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               //将bean提前暴露,并从移除singletonFactories(什么时候放进singletonFactories?)
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

可以发现是#getSingleton方法, 思考两个问题

  • 什么时候放进去singletonsCurrentlyInCreation?
  • 什么时候放进singletonFactories?

问题1–> 在#beforeSingletonCreation方法中可以看到

protected void beforeSingletonCreation(String beanName) {
  //是否在不需要检查的集合中,并且不在正在创建的集合中(循环依赖检查)
   if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
      throw new BeanCurrentlyInCreationException(beanName);
   }
}

该方法在其父类中调用.

singletonFactories

在#addSingletonFactory中

/**
 * Add the given singleton factory for building the specified singleton
 * if necessary.
 * <p>To be called for eager registration of singletons, e.g. to be able to
 * resolve circular references.
 * @param beanName the name of the bean
 * @param singletonFactory the factory for the singleton object
 */
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);
      }
   }
}

问题2–>可以发现registeredSingletons , singletonFactories 都在这里调用, 该方法在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中调用

singletonObjects

我们再看下主角singletonObjects 是怎么初始化的

/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
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);
   }
}

addSingleton的调用在#registerSingleton 以及 getSingleton(String,ObjectFactory<?>)

@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
   Assert.notNull(beanName, "Bean name must not be null");
   Assert.notNull(singletonObject, "Singleton object must not be null");
   synchronized (this.singletonObjects) {
      Object oldObject = this.singletonObjects.get(beanName);
      if (oldObject != null) {
         throw new IllegalStateException("Could not register object [" + singletonObject +
               "] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
      }
      addSingleton(beanName, singletonObject);
   }
}

至此,DefaultSingletonBeanRegistry 的分析差不多了.

更多细节:https://www.cnblogs.com/binarylei/p/10326046.html

BeanFactory

接下来我们来看下完整的调用顺序 从BeanFactory#getBean(java.lang.Class)说起

DefaultListableBeanFactory#getBean

@SuppressWarnings("unchecked")
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
   Object resolved = resolveBean(ResolvableType.forRawClass(requiredType), args, false);
   if (resolved == null) {
      throw new NoSuchBeanDefinitionException(requiredType);
   }
   return (T) resolved;
}

DefaultListableBeanFactory#resolveBean

@Nullable
private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
    //从当前容器中获取
    NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull);
    if (namedBean != null) {
        return namedBean.getBeanInstance();
    }
  //如果不存在,查询父容器是否存在
    BeanFactory parent = getParentBeanFactory();
    if (parent instanceof DefaultListableBeanFactory) {
        return ((DefaultListableBeanFactory) parent).resolveBean(requiredType, args, nonUniqueAsNull);
    }
    else if (parent != null) {
        ObjectProvider<T> parentProvider = parent.getBeanProvider(requiredType);
        if (args != null) {
            return parentProvider.getObject(args);
        }
        else {
            return (nonUniqueAsNull ? parentProvider.getIfUnique() : parentProvider.getIfAvailable());
        }
    }
    return null;
}

DefaultListableBeanFactory#resolveNamedBean

@SuppressWarnings("unchecked")
@Nullable
private <T> NamedBeanHolder<T> resolveNamedBean(
      ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {

   Assert.notNull(requiredType, "Required type must not be null");
   //检查所有的bean definitions. (bean definitions 时候写入? )
   String[] candidateNames = getBeanNamesForType(requiredType);

   //过滤处理
   if (candidateNames.length > 1) {
      List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
      for (String beanName : candidateNames) {
         if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
            autowireCandidates.add(beanName);
         }
      }
      if (!autowireCandidates.isEmpty()) {
         candidateNames = StringUtils.toStringArray(autowireCandidates);
      }
   }

   if (candidateNames.length == 1) {
      String beanName = candidateNames[0];
      //先只关注这里 ,只有一个候选的时候
      return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args));
   }
   else if (candidateNames.length > 1) {
      Map<String, Object> candidates = new LinkedHashMap<>(candidateNames.length);
      for (String beanName : candidateNames) {
         if (containsSingleton(beanName) && args == null) {
            Object beanInstance = getBean(beanName);
            candidates.put(beanName, (beanInstance instanceof NullBean ? null : beanInstance));
         }
         else {
            candidates.put(beanName, getType(beanName));
         }
      }
      String candidateName = determinePrimaryCandidate(candidates, requiredType.toClass());
      if (candidateName == null) {
         candidateName = determineHighestPriorityCandidate(candidates, requiredType.toClass());
      }
      if (candidateName != null) {
         Object beanInstance = candidates.get(candidateName);
         if (beanInstance == null || beanInstance instanceof Class) {
            beanInstance = getBean(candidateName, requiredType.toClass(), args);
         }
         return new NamedBeanHolder<>(candidateName, (T) beanInstance);
      }
      if (!nonUniqueAsNull) {
         throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
      }
   }

   return null;
}

先只关注只有一个候选者的情况

AbstractBeanFactory#GetBean

/**
 * 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)
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
      throws BeansException {

   return doGetBean(name, requiredType, args, false);
}

==AbstractBeanFactory#doGetBean==

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        
    //beanClass Name处理
    final String beanName = transformedBeanName(name);
    //缓存实例
    // Eagerly check singleton cache for manually registered singletons. 
        Object sharedInstance = getSingleton(beanName);
    ...
     //如果存在缓存直接调用
      if (sharedInstance != null && args == null) {
                   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();
       
      //beanDefinition处理  
      final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);
      
       //dependsOn处理  
      // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
      registerDependentBean(dep, beanName);
            try {
                 getBean(dep);
            }
                ...
      //根据scope创建    
            // 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);
                }      
    }
}

#transformedBeanName : 名字处理

#getSingleton : 循环依赖和缓存

​ 第一次调用getSingleton,这里返回 null ,因为缓存中不存在

​ 第二次,调用getSingleton DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

​ (其中调用了#beforeSingletonCreation (正在实例化的bean添加进去))

#getParentBeanFactory : 父容器查找(当前容器不存在)

#getMergedLocalBeanDefinition : beanDefinition处理,dependsOn处理

#createBean 创建bean逻辑

#getSingleton缓存bean

AbstractAutowireCapableBeanFactory#createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
    ...
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      try {
      //InstantiationAwareBeanPostProcessor 去创建bean 
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }
        try {
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }  
}

tips : InstantiationAwareBeanPostProcessor 前置处理器

==AbstractAutowireCapableBeanFactory#doCreateBean==

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
 // 实例化 Instantiate the bean.  在内存中创建了bean 属性还没填充
 //instantiation strategy :factory method, constructor autowiring, or simple instantiation.
    // 默认使用cglib
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    
        // 允许后置处理器来修改这个BeanDefinition
        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;
            }
        } 	
        
  
    //提前暴露解决循环依赖问题
        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));
        }  
  
   // 初始化bean实例。
   //通过beanDefinition 填充BeanWrapper 属性值
        populateBean(beanName, mbd, instanceWrapper);

   //进行一些初始化方法的调用,比如afterPropertiesSet等等。
        exposedObject = initializeBean(beanName, exposedObject, mbd);  
  
    //提前暴露的类检查,防止非代理对象被提前暴露注入,导致两个bean不一致
        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);
        }
}

这里调用了addSingletonFactory

在 bean 初始化完成还后还需要进行依赖的检查,这时因为提前暴露的这个 bean(即使用工厂方法或构造方法创建出来的对象) initializeBean 还可以进行增强(例如aop代理),这样这两个 bean 就不是同一个了。Spring 默认是不允许这种情况发生的。

AbstractAutowireCapableBeanFactory#createBeanInstance

实例化

方式 根据工厂方法、构造函数、默认方式

方法:CGLIB/JDK

@see #instantiateUsingFactoryMethod
@see #autowireConstructor
@see #instantiateBean

AbstractAutowireCapableBeanFactory#populateBean

ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)

autowireByName(beanName, mbd, bw, newPvs) or autowireByType(beanName, mbd, bw, newPvs);

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

applyPropertyValues(beanName, mbd, bw, pvs);

AbstractAutowireCapableBeanFactory#initializeBean

invokeAwareMethods

  • @see BeanNameAware
  • @see BeanClassLoaderAware
  • @see BeanFactoryAware

@see #applyBeanPostProcessorsBeforeInitialization

@see #invokeInitMethods

@see #applyBeanPostProcessorsAfterInitialization

至此getBean调用结束,可以通过调试模拟下

代码:

BeanClass 用于被加载的class

public class BeanClass {
    public BeanClass() {
        System.out.println("init...");
    }

}

BeanFactory引导类

public class ContainerStarter {
    public static void main(String[] args) {
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(
                new ClassPathResource("application.xml"));
        //获取Bean 实例
        xmlBeanFactory.getBean(BeanClass.class);
    }
}

resources目录下的xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="beanClass" class="beanfatory.BeanClass"></bean>
</beans>

==Bean初始化流程图==

主要是在下面的两个类, 简单划分为两个阶段

  • 准备阶段(AbstractBeanFactory#doGetBean)

    • 从缓存中获取
    • 循环依赖检查
    • BeanDefinition检查、合并
    • 依赖Bean检查、创建 (dependsOn)
    • 根据scope创建
  • 实例化阶段(AbstractAutowireCapableBeanFactory#doCreateBean)

    • 允许InstantiationAwareBeanPostProcessor 返回代理 (AOP的实现, 代理也会回调BeanPostProcessor的处理)
    • 实例化 (默认、工厂、构造函数)
    • MergedBeanDefinitionPostProcessor修改BeanDeinition
    • 提前暴露Bean
    • 属性填充
    • 初始化(接口的回调)
      • AwareMethods
      • BPP-Before
      • invokeMethods (afterProperts、init-method)
      • BBP-After

    简单流程如下:

Spirng 对 Bean 的处理

详细的流程图可以参考某位大佬的:https://blog.csdn.net/zghwaicsdn/article/details/50910384

BeanDefinitionRegistry

接下来看看BeanDefinition是什么,BeanDefinition是在哪里注册的,BeanDefinition是怎么来的

BeanDefinition

继承体系

image-20191205212750684

BeanDefinition信息

先来看看BeanDefinition,BeanDefinition描述了一个bean实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息。

主要目的是允许 BeanFactoryPostProcessor,例如 PropertyPlaceholderConfigurer 内省和修改, 属性值和其他bean元数据。

获取上述的BeanClass 打印信息如下

Generic bean: class [beanfatory.BeanClass]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [application.xml]

可以得知 它具有哪些属性,以及它是一个GenericBeanDefinition

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    //scope值,单例还是非单例
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
  
    //Bean角色:
    //用户
    int ROLE_APPLICATION = 0;
    //某些复杂的配置
    int ROLE_SUPPORT = 1;
    //完全内部使用
    int ROLE_INFRASTRUCTURE = 2;

    //返回此bean定义的父bean定义的名称,如果有的话 <bean parent="">
    String getParentName();
    void setParentName(String parentName);

    //获取bean对象className <bean class="">
    String getBeanClassName();
    void setBeanClassName(String beanClassName);

    //定义创建该Bean对象的工厂类  <bean factory-bean="">
    String getFactoryBeanName();
    void setFactoryBeanName(String factoryBeanName);

    //定义创建该Bean对象的工厂方法 <bean factory-method="">
    String getFactoryMethodName();
    void setFactoryMethodName(String factoryMethodName);

    //<bean scope="singleton/prototype">
    String getScope();
    void setScope(String scope);

    //懒加载 <bean lazy-init="true/false">
    boolean isLazyInit();
    void setLazyInit(boolean lazyInit);

    //依赖对象  <bean depends-on="">
    String[] getDependsOn();
    void setDependsOn(String[] dependsOn);

    //是否为被自动装配 <bean autowire-candidate="true/false">
    boolean isAutowireCandidate();
    void setAutowireCandidate(boolean autowireCandidate);

    //是否为主候选bean    使用注解:@Primary
    boolean isPrimary();
    void setPrimary(boolean primary);

    //返回此bean的构造函数参数值。
    ConstructorArgumentValues getConstructorArgumentValues();

    //获取普通属性集合
    MutablePropertyValues getPropertyValues();

    boolean isSingleton();
    boolean isPrototype();
    boolean isAbstract();
    int getRole();

    //返回对bean定义的可读描述。
    String getDescription();
    //返回该bean定义来自的资源的描述(用于在出现错误时显示上下文)
    String getResourceDescription();
    BeanDefinition getOriginatingBeanDefinition();
}
}
AbstractBeanDefinition

Base class for concrete, full-fledged {@link BeanDefinition} classes, factoring out common properties of {@link GenericBeanDefinition}, {@link RootBeanDefinition}, and {@link ChildBeanDefinition}.

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
      implements BeanDefinition, Cloneable {
  ...
}

BeanDefinition基础实现类,另外继承了BeanMetadataAttributeAccessor(元数据属性 )

public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
    public void addMetadataAttribute(BeanMetadataAttribute attribute) {
        super.setAttribute(attribute.getName(), attribute);
    }
    @Nullable
    public BeanMetadataAttribute getMetadataAttribute(String name) {
        return (BeanMetadataAttribute) super.getAttribute(name);
    }
  ....
}
public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
    /** Map with String keys and Object values. */
    private final Map<String, Object> attributes = new LinkedHashMap<>();
  ...
}

在AttributeAccessorSupport 中维护了k-name ,v-BeanMetadata 的map

BeanMetadataAttribute: Holder for a key-value style attribute that is part of a bean definition.
Keeps track of the definition source in addition to the key-value pair.

再来看看三个实现类

  • GenericBeanDefinition
  • RootBeanDefinition
  • ChildBeanDefinition
RootBeanDefinition

A root bean definition represents the merged bean definition that backs a specific bean in a Spring BeanFactory at runtime.It might have been created from multiple original bean definitions that inherit from each other, typically registered as GenericBeanDefinitions. A root bean definition is essentially the ‘unified’ bean definition view at runtime.Root bean definitions may also be used for registering individual bean definitions in the configuration phase.

However, since Spring 2.5, the preferred way to register bean definitions programmatically is the GenericBeanDefinition class. GenericBeanDefinition has the advantage that it allows to dynamically define parent dependencies, not ‘hard-coding’ the role as a root bean definition.

root bean定义表示在运行时支持Spring BeanFactory中特定bean 的merge dbean定义。它可能是由多个相互继承的原始bean定义创建的,通常注册为genericbeandefinition。root bean定义本质上是运行时的“统一”bean定义视图。root bean定义也可以用于在配置阶段注册各个bean定义。

但是,自spring2.5以来,以编程方式注册bean定义的首选方法是GenericBeanDefinition类。GenericBeanDefinition的优点是它允许动态定义父依赖项,而不是将角色“硬编码”为root bean。

public class RootBeanDefinition extends AbstractBeanDefinition {
    @Override
    public String getParentName() {
        return null;
    }

    @Override
    public void setParentName(@Nullable String parentName) {
        if (parentName != null) {
            throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
        }
    }
  ...
}
ChildBeanDefinition

Bean definition for beans which inherit settings from their parent. Child bean definitions have a fixed dependency on a parent bean definition.
A child bean definition will inherit constructor argument values, property values and method overrides from the parent, with the option to add new values. If init method, destroy method and/or static factory method are specified, they will override the corresponding parent settings. The remaining settings will always be taken from the child definition: depends on, autowire mode, dependency check, singleton, lazy init.

NOTE: Since Spring 2.5, the preferred way to register bean definitions programmatically is the GenericBeanDefinition class, which allows to dynamically define parent dependencies through the GenericBeanDefinition.setParentName(java.lang.String) method. This effectively supersedes the ChildBeanDefinition class for most use cases.

Bean定义,用于从父类继承设置的Bean。子bean定义对父bean定义有固定的依赖关系。

子bean定义将继承父类的构造函数参数值、属性值和方法重写,并可选择添加新值。如果指定了init方法、destroy方法和/或静态工厂方法,它们将覆盖相应的父设置。

其余的设置将始终从子定义:依赖、自动装配模式、依赖项检查、单例、惰性初始化。

注意:自spring2.5以来,以编程方式注册bean定义的首选方法是GenericBeanDefinition类,它允许通过GenericBeanDefinition. setParentName (java.lang.String)方法动态定义父依赖项。对于大多数用例,这实际上取代了ChildBeanDefinition类。

public class ChildBeanDefinition extends AbstractBeanDefinition {
        @Override
    public void setParentName(@Nullable String parentName) {
        this.parentName = parentName;
    }

    @Override
    @Nullable
    public String getParentName() {
        return this.parentName;
    }

    @Override
    public void validate() throws BeanDefinitionValidationException {
        super.validate();
        if (this.parentName == null) {
            throw new BeanDefinitionValidationException("'parentName' must be set in ChildBeanDefinition");
        }
    }
}

可以看到从2.5开始 Child 和 Root 都被GenericBeanDefinition替代 ,其中重要的原因是允许动态定义父依赖

GenericBeanDefinition

GenericBeanDefinition is a one-stop shop for standard bean definition purposes. Like any bean definition, it allows for specifying a class plus optionally constructor argument values and property values. Additionally, deriving from a parent bean definition can be flexibly configured through the “parentName” property. In general, use this GenericBeanDefinition class for the purpose of registering user-visible bean definitions (which a post-processor might operate on, potentially even reconfiguring the parent name). Use RootBeanDefinition / ChildBeanDefinition where parent/child relationships happen to be pre-determined.

GenericBeanDefinition是标准bean定义的一站式服务。与任何bean定义一样,它允许指定一个类加上可选的构造函数参数值和属性值。此外,可以通过“parentName”属性灵活地配置来自父bean定义的派生。

通常,使用这个GenericBeanDefinition类的目的是注册用户可见的bean定义(后处理器可以对其进行操作,甚至可能重新配置父名称)。使用RootBeanDefinition / ChildBeanDefinition来预先确定父/子关系。

public class GenericBeanDefinition extends AbstractBeanDefinition {
   @Nullable
   private String parentName;
   ...
  /**
     * Create a new GenericBeanDefinition, to be configured through its bean
     * properties and configuration methods.
     * @see #setBeanClass
     * @see #setScope
     * @see #setConstructorArgumentValues
     * @see #setPropertyValues
     */
    public GenericBeanDefinition() {
        super();
    }
}
ConfigurationClassBeanDefinition
class org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition(){
  
}
/**
 * Build and validate a configuration model based on the registry of
 * {@link Configuration} classes.
 */
public void org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions(BeanDefinitionRegistry registry){
   
}

更多细节:

@see ConfigurationClassPostProcessor

@see ConfigurationClassBeanDefinitionReader

@see ConfigurationClassParser

AbstractBeanFactory#getMergedBeanDefinition
/**
 * Return a RootBeanDefinition for the given bean, by merging with the
 * parent if the given bean's definition is a child bean definition.
 * @param beanName the name of the bean definition
 * @param bd the original bean definition (Root/ChildBeanDefinition)
 * @param containingBd the containing bean definition in case of inner bean,
 * or {@code null} in case of a top-level bean
 * @return a (potentially merged) RootBeanDefinition for the given bean
 * @throws BeanDefinitionStoreException in case of an invalid bean definition
 */
protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

   synchronized (this.mergedBeanDefinitions) {
      RootBeanDefinition mbd = null;

      // Check with full lock now in order to enforce the same merged instance.
      if (containingBd == null) {
         mbd = this.mergedBeanDefinitions.get(beanName);
      }

      if (mbd == null) {
         if (bd.getParentName() == null) {
            // Use copy of given root bean definition.
            if (bd instanceof RootBeanDefinition) {
               mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            }
            else {
               mbd = new RootBeanDefinition(bd);
            }
         }
         else {
            // Child bean definition: needs to be merged with parent.
            BeanDefinition pbd;
            try {
               String parentBeanName = transformedBeanName(bd.getParentName());
               if (!beanName.equals(parentBeanName)) {
                  pbd = getMergedBeanDefinition(parentBeanName);
               }
               else {
                  BeanFactory parent = getParentBeanFactory();
                  if (parent instanceof ConfigurableBeanFactory) {
                     pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                  }
                  else {
                     throw new NoSuchBeanDefinitionException(parentBeanName,
                           "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                           "': cannot be resolved without an AbstractBeanFactory parent");
                  }
               }
            }
            catch (NoSuchBeanDefinitionException ex) {
               throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                     "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
            }
            //进行深拷贝, 合并、 覆盖父类overridden方法 
            mbd = new RootBeanDefinition(pbd);
            mbd.overrideFrom(bd);
         }

         // Set default singleton scope, if not configured before.
         if (!StringUtils.hasLength(mbd.getScope())) {
            mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
         }

         // A bean contained in a non-singleton bean cannot be a singleton itself.
         // Let's correct this on the fly here, since this might be the result of
         // parent-child merging for the outer bean, in which case the original inner bean
         // definition will not have inherited the merged outer bean's singleton status.
         if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
            mbd.setScope(containingBd.getScope());
         }

         // Cache the merged bean definition for the time being
         // (it might still get re-merged later on in order to pick up metadata changes)
         if (containingBd == null && isCacheBeanMetadata()) {
            this.mergedBeanDefinitions.put(beanName, mbd);
         }
      }

      return mbd;
   }
}
  1. 在mergedBeanDefinitions同步的情况下再次读取缓存,防止该BeanDefinition已经被合并过了。
  2. 检查是否有父类,若有父类,则必须递归去合并BeanDefinition。
  3. 将子类重写后的方法覆盖到定义的BeanDefinition中。
  4. 设置scope类型。
  5. 将生成的BeanDefinition缓存起来。

BeanDefinitionRegistry

public interface BeanDefinitionRegistry extends AliasRegistry {
        void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException;
      void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
      BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
        boolean containsBeanDefinition(String beanName);
        String[] getBeanDefinitionNames();
        int getBeanDefinitionCount();
        boolean isBeanNameInUse(String beanName);
}
  1. 首先是实现,实现方式是怎么样的?

registerBeanDefinition 在哪里实现 , 可以定位到 DefaultListableBeanFactory中

//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//---------------------------------------------------------------------

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
     //校验
   ((AbstractBeanDefinition) beanDefinition).validate();
        ...
     //已存在的处理
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
   if (existingDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
         throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      }
            //省略日志打印
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   else {
      if (hasBeanCreationStarted()) {
         // Cannot modify startup-time collection elements anymore (for stable iteration)
         synchronized (this.beanDefinitionMap) {
            this.beanDefinitionMap.put(beanName, beanDefinition);
            List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            if (this.manualSingletonNames.contains(beanName)) {
               Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
               updatedSingletons.remove(beanName);
               this.manualSingletonNames = updatedSingletons;
            }
         }
      }
      else {
         // Still in startup registration phase
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         this.manualSingletonNames.remove(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }
   if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   }
}

简单来说就是干了以下的事情

this.beanDefinitionMap.put(beanName, beanDefinition);

this.beanDefinitionNames.add(beanName);

this.manualSingletonNames.remove(beanName);

  1. 那么在哪里调用?BeanDefinition是怎么来的?

从XmlBeanFactory 中可以发现 XmlBeanDefinitionReader 的作用是loadBeanDefinitions ,那么我们先从其父类说起

image-20191208233705110

BeanDefinitionReader

package org.springframework.beans.factory.support;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.Nullable;

/**
 * Simple interface for bean definition readers.
 * Specifies load methods with Resource and String location parameters.
 *
 * <p>Concrete bean definition readers can of course add additional
 * load and register methods for bean definitions, specific to
 * their bean definition format.
 *
 * <p>Note that a bean definition reader does not have to implement
 * this interface. It only serves as suggestion for bean definition
 * readers that want to follow standard naming conventions.
 *
 * @author Juergen Hoeller
 * @since 1.1
 * @see org.springframework.core.io.Resource
 */
public interface BeanDefinitionReader {
   BeanDefinitionRegistry getRegistry();
   @Nullable
   ResourceLoader getResourceLoader();
   @Nullable
   ClassLoader getBeanClassLoader();
   BeanNameGenerator getBeanNameGenerator();

   int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
   int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
   int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
   int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}

可以看到这个Reader 在整个BeanFactory中的重要性, 其作用根据接口我们可以猜测出是 资源定位 解析 注册

@see ResourceLoader

@see ClassLoader

@see BeanNameGenerator

XmlBeanDefinitionReader

调用链请看

org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions

org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions

org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseBeanDefinitionElement(org.w3c.dom.Element)

org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition

详细

@see AbstractBeanDefinitionReader

@see DefaultBeanDefinitionDocumentReader

@see BeanDefinitionParserDelegate

@see BeanDefinitionReaderUtils

最后

todo 总结


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951488791@qq.com

文章标题:spring-BeanFactory

字数:7k

本文作者:zhengyumin

发布时间:2019-12-05, 21:28:57

最后更新:2020-07-24, 16:27:38

原始链接:http://zyumin.github.io/2019/12/05/spring-BeanFactory/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。