抽象工厂Bean,承上启下,定义架构
package com.geely.online.testdriver; import java.beans.PropertyEditor; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyEditorRegistrar; import org.springframework.beans.PropertyEditorRegistry; import org.springframework.beans.PropertyEditorRegistrySupport; import org.springframework.beans.SimpleTypeConverter; import org.springframework.beans.TypeConverter; import org.springframework.beans.TypeMismatchException; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanIsAbstractException; import org.springframework.beans.factory.BeanIsNotAFactoryException; import org.springframework.beans.factory.BeanNotOfRequiredTypeException; import org.springframework.beans.factory.CannotLoadBeanClassException; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.SmartFactoryBean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionResolver; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; import org.springframework.beans.factory.config.Scope; import org.springframework.beans.factory.support.*; import org.springframework.core.AttributeAccessor; import org.springframework.core.DecoratingClassLoader; import org.springframework.core.NamedThreadLocal; import org.springframework.core.ResolvableType; import org.springframework.core.convert.ConversionService; import org.springframework.core.log.LogMessage; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.util.StringValueResolver; /** * // BeanFactory 的基础抽象实现类 * Abstract base class for {@link org.springframework.beans.factory.BeanFactory} * implementations, * * //提供了 可配置BeanFactory.SPI完整能力实现 * providing the full capabilities of the * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} SPI. * Does <i>not</i> assume a listable bean factory: * * // 可以作为BeanFactory的基本实现 * can therefore also be used * as base class for bean factory implementations which obtain bean definitions * from some backend resource (where bean definition access is an expensive operation). * * // 通过 defaultSingletonBeanRegistry(默认单例bean注册器),提供了单例对象缓存能力 * <p>This class provides a singleton cache (through its base class * {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry}, * * // 单例/原型判定,处理,别名,为子类bean定义做合并 * singleton/prototype determination, {@link org.springframework.beans.factory.FactoryBean} * handling, aliases, bean definition merging for child bean definitions, * * //bena销毁 (一次性bean和 自定义销毁方法的) * and bean destruction ({@link org.springframework.beans.factory.DisposableBean} * interface, custom destroy methods). * * // 更进一步,他能管理bean Factory层级关系, (层级Bean工厂) * Furthermore, it can manage a bean factory * hierarchy (delegating to the parent in case of an unknown bean), through implementing * the {@link org.springframework.beans.factory.HierarchicalBeanFactory} interface. * * * // 主要需要被子类实现的方法是 getBeanDefinition 和 createBean * <p>The main template methods to be implemented by subclasses are * {@link #getBeanDefinition} and {@link #createBean}, * retrieving a bean definition for a given bean name * and creating a bean instance for a given bean definition, * * respectively. Default implementations of those operations can be found in * {@link DefaultListableBeanFactory} and {@link AbstractAutowireCapableBeanFactory}. * * DefaultListableBeanFactory 默认可罗列的bean工厂 * AbstractAutowireCapableBeanFactory 抽象的带自动装配能力的Bean工厂 * * @author Rod Johnson * @author Juergen Hoeller * @author Costin Leau * @author Chris Beams * @author Phillip Webb * @since 15 April 2001 * @see #getBeanDefinition * @see #createBean * @see AbstractAutowireCapableBeanFactory#createBean * @see DefaultListableBeanFactory#getBeanDefinition */ // 抽象bean工厂(AbstractBeanFactory) public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { //FactoryBeanRegistrySupport 工厂bean注册支持者,抽象类 (支持从工厂bean中获得bean,删除bean等) //ConfigurableBeanFactory 可配置bean工厂,接口 (设置父bean工厂,类加载器,类型转化器,属性编辑器,字符串解析器,设置scope,后置处理器等) //父bean工厂,用来支持bean的继承 /** Parent bean factory, for bean inheritance support. */ @Nullable private BeanFactory parentBeanFactory; //类加载器,用来解析类的名称,如果有需要(默认是线程上下文类加载器) /** ClassLoader to resolve bean class names with, if necessary. */ @Nullable private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); //类加载器,用来临时解析bean类的名称,如果有需求 /** ClassLoader to temporarily resolve bean class names with, if necessary. */ @Nullable private ClassLoader tempClassLoader; //是缓存bean的元数据,还是每次访问的时候都重新获取,默认true,缓存 /** Whether to cache bean metadata or rather reobtain it for every access. */ private boolean cacheBeanMetadata = true; //bean定义信息的表达式解析器 /** Resolution strategy for expressions in bean definition values. */ @Nullable private BeanExpressionResolver beanExpressionResolver; //转化服务,用来代替属性编辑器 /** Spring ConversionService to use instead of PropertyEditors. */ @Nullable private ConversionService conversionService; // 自定义属性编辑器注册器,作用于当前这个工厂的beans /** Custom PropertyEditorRegistrars to apply to the beans of this factory. */ private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4); // 自定义的属性编辑器,作用于当前这个工厂的beans (PECS,,,生产者容器,可以使用这个容器的对象做事情) /** Custom PropertyEditors to apply to the beans of this factory. */ private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4); // 一个自定义的类型转化器,用来覆盖默认设置的属性编辑器 /** A custom TypeConverter to use, overriding the default PropertyEditor mechanism. */ @Nullable private TypeConverter typeConverter; //内嵌的值解析器,字符传解析器,比如,注解中的属性值 /** String resolvers to apply e.g. to annotation attribute values. */ private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>(); // 应用的bean后置处理器s (线程安全的,写时复制数值列表) /** BeanPostProcessors to apply. */ private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>(); // 用来标识是否存在特殊的bean后置处理器(instantiationAware 实例化感知的后置处理器) /** Indicates whether any InstantiationAwareBeanPostProcessors have been registered. */ private volatile boolean hasInstantiationAwareBeanPostProcessors; // 用来标识是否存在特殊的bean后置处理器 (destrunctionAware 销毁感知的bean后置处理器) /** Indicates whether any DestructionAwareBeanPostProcessors have been registered. */ private volatile boolean hasDestructionAwareBeanPostProcessors; //字符串-> 作用域 的映射关系 /** Map from scope identifier String to corresponding Scope. */ private final Map<String, Scope> scopes = new LinkedHashMap<>(8); //当运行在一个安全管理器下面时,需要使用一个安全的上下文环境 /** Security context used when running with a SecurityManager. */ @Nullable private SecurityContextProvider securityContextProvider; //bean 名称-> 根定义 /** Map from bean name to merged RootBeanDefinition. */ private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256); //至少被创建了一次的bean的名称 /** Names of beans that have already been created at least once. */ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); //线程本地变量 (正在创建属性bean,一个对象关联到的属性bean) /** Names of beans that are currently in creation. */ private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation"); /** * Create a new AbstractBeanFactory. */ public AbstractBeanFactory() { } /** * Create a new AbstractBeanFactory with the given parent. * @param parentBeanFactory parent bean factory, or {@code null} if none * @see #getBean */ public AbstractBeanFactory(@Nullable BeanFactory parentBeanFactory) { this.parentBeanFactory = parentBeanFactory; } //--------------------------------------------------------------------- // Implementation of BeanFactory interface 实现bean工厂的接口 //--------------------------------------------------------------------- @Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, 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) * @return an instance of the bean * @throws BeansException if the bean could not be created */ //返回特定的一个bean实例,可能时共享的,也可能是非独立的 public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException { return doGetBean(name, requiredType, args, 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 // 得到当前bean,是否只是用来做类型校验 * @return an instance of the bean * @throws BeansException if the bean could not be created */ @SuppressWarnings("unchecked") protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //=================1.转化得到标准的bean名称 (去掉& ,别名转成标准名) =============== String beanName = transformedBeanName(name); Object bean; //=================2 得到bean的主体业务逻辑 =============== // Eagerly check singleton cache for manually registered singletons. // 检查手动注册单例对象 // 从默认单例注册器中查找是否存在(3级缓存,单例对象集,早产单例对象集,单例工厂集合) Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //--------------------2.1 小概率业务场景处 if (logger.isTraceEnabled()) { //当前这个bean是否正在被创建 if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } // 从bean实例中得到需要暴露的对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //--------------------2.2 大部分业务场景处 // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 存在父容器(beanFactory),自身容器没有bean定义信息 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof org.springframework.beans.factory.support.AbstractBeanFactory) { return ((org.springframework.beans.factory.support.AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } //没有父容器,或者有自己的bean定义信息 try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //a,得到我依赖的对象 // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { //我依赖他(dep),他又反过来依赖我,循环依赖 if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } //注册依赖bean关系 registerDependentBean(dep, beanName); try { //得到我这个对象依赖的其他bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } //2,创建自身实例 // Create bean instance. if (mbd.isSingleton()) { //2.1 ,单例对象 //得到单例,从默认单例对象注册器获取,如果没有,就触发工厂的创建方法 //getSingleton(String beanName, ObjectFactory<?> singletonFactory) 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()) { //2.2 ,原型模型 // 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 { //2.3 ,自定义作用域 String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { // 得到某个特殊作用域的实例 Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); // 统一,从beanInstance 得到object 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. //================= 3.判断需要的类型和实际的bean是否匹配=========================== if (requiredType != null && !requiredType.isInstance(bean)) { try { // 类型转化器,将得到的类型,转成需要的类型 T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) {//类型不匹配异常 if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } //得到的bean 不是需要的类型异常 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } @Override public boolean containsBean(String name) { String beanName = transformedBeanName(name); if (containsSingleton(beanName) || containsBeanDefinition(beanName)) { return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name)); } // Not found -> check parent. BeanFactory parentBeanFactory = getParentBeanFactory(); return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name))); } // 判断是否又这个单例,不是创建,不允许循环依赖,只能使用一级或者二级缓存 //singletonObjects earlySingletonObjects @Override public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); Object beanInstance = getSingleton(beanName, false); if (beanInstance != null) { if (beanInstance instanceof FactoryBean) { return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean<?>) beanInstance).isSingleton()); } else { return !BeanFactoryUtils.isFactoryDereference(name); } } // No singleton instance found -> check bean definition. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // No bean definition found in this factory -> delegate to parent. return parentBeanFactory.isSingleton(originalBeanName(name)); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // In case of FactoryBean, return singleton status of created object if not a dereference. if (mbd.isSingleton()) { if (isFactoryBean(beanName, mbd)) { if (BeanFactoryUtils.isFactoryDereference(name)) { return true; } FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); return factoryBean.isSingleton(); } else { return !BeanFactoryUtils.isFactoryDereference(name); } } else { return false; } } @Override public boolean isPrototype(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // No bean definition found in this factory -> delegate to parent. return parentBeanFactory.isPrototype(originalBeanName(name)); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); if (mbd.isPrototype()) { // In case of FactoryBean, return singleton status of created object if not a dereference. return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd)); } // Singleton or scoped - not a prototype. // However, FactoryBean may still produce a prototype object... if (BeanFactoryUtils.isFactoryDereference(name)) { return false; } if (isFactoryBean(beanName, mbd)) { FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); if (System.getSecurityManager() != null) { return AccessController.doPrivileged( (PrivilegedAction<Boolean>) () -> ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || !fb.isSingleton()), getAccessControlContext()); } else { return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) || !fb.isSingleton()); } } else { return false; } } // 是否类型匹配 @Override public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException { return isTypeMatch(name, typeToMatch, true); } /** * Internal extended variant of {@link #isTypeMatch(String, ResolvableType)} * to check whether the bean with the given name matches the specified type. Allow * additional constraints to be applied to ensure that beans are not created early. * @param name the name of the bean to query * @param typeToMatch the type to match against (as a * {@code ResolvableType}) * @return {@code true} if the bean type matches, {@code false} if it * doesn't match or cannot be determined yet * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @since 5.2 * @see #getBean * @see #getType */ protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name); // Check manually registered singletons. Object beanInstance = getSingleton(beanName, false); if (beanInstance != null && beanInstance.getClass() != NullBean.class) { if (beanInstance instanceof FactoryBean) { if (!isFactoryDereference) { Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance); return (type != null && typeToMatch.isAssignableFrom(type)); } else { return typeToMatch.isInstance(beanInstance); } } else if (!isFactoryDereference) { if (typeToMatch.isInstance(beanInstance)) { // Direct match for exposed instance? return true; } else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) { // Generics potentially only match on the target class, not on the proxy... RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); Class<?> targetType = mbd.getTargetType(); if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) { // Check raw class match as well, making sure it's exposed on the proxy. Class<?> classToMatch = typeToMatch.resolve(); if (classToMatch != null && !classToMatch.isInstance(beanInstance)) { return false; } if (typeToMatch.isAssignableFrom(targetType)) { return true; } } ResolvableType resolvableType = mbd.targetType; if (resolvableType == null) { resolvableType = mbd.factoryMethodReturnType; } return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType)); } } return false; } else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) { // null instance registered return false; } // No singleton instance found -> check bean definition. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // No bean definition found in this factory -> delegate to parent. return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch); } // Retrieve corresponding bean definition. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); // Setup the types that we want to match against Class<?> classToMatch = typeToMatch.resolve(); if (classToMatch == null) { classToMatch = FactoryBean.class; } Class<?>[] typesToMatch = (FactoryBean.class == classToMatch ? new Class<?>[] {classToMatch} : new Class<?>[] {FactoryBean.class, classToMatch}); // Attempt to predict the bean type Class<?> predictedType = null; // We're looking for a regular reference but we're a factory bean that has // a decorated bean definition. The target bean should be the same type // as FactoryBean would ultimately return. if (!isFactoryDereference && dbd != null && isFactoryBean(beanName, mbd)) { // We should only attempt if the user explicitly set lazy-init to true // and we know the merged bean definition is for a factory bean. if (!mbd.isLazyInit() || allowFactoryBeanInit) { RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); Class<?> targetType = predictBeanType(dbd.getBeanName(), tbd, typesToMatch); if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) { predictedType = targetType; } } } // If we couldn't use the target type, try regular prediction. if (predictedType == null) { predictedType = predictBeanType(beanName, mbd, typesToMatch); if (predictedType == null) { return false; } } // Attempt to get the actual ResolvableType for the bean. ResolvableType beanType = null; // If it's a FactoryBean, we want to look at what it creates, not the factory class. if (FactoryBean.class.isAssignableFrom(predictedType)) { if (beanInstance == null && !isFactoryDereference) { beanType = getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit); predictedType = beanType.resolve(); if (predictedType == null) { return false; } } } else if (isFactoryDereference) { // Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean // type but we nevertheless are being asked to dereference a FactoryBean... // Let's check the original bean class and proceed with it if it is a FactoryBean. predictedType = predictBeanType(beanName, mbd, FactoryBean.class); if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) { return false; } } // We don't have an exact type but if bean definition target type or the factory // method return type matches the predicted type then we can use that. if (beanType == null) { ResolvableType definedType = mbd.targetType; if (definedType == null) { definedType = mbd.factoryMethodReturnType; } if (definedType != null && definedType.resolve() == predictedType) { beanType = definedType; } } // If we have a bean type use it so that generics are considered if (beanType != null) { return typeToMatch.isAssignableFrom(beanType); } // If we don't have a bean type, fallback to the predicted type return typeToMatch.isAssignableFrom(predictedType); } @Override public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException { return isTypeMatch(name, ResolvableType.forRawClass(typeToMatch)); } @Override @Nullable public Class<?> getType(String name) throws NoSuchBeanDefinitionException { return getType(name, true); } @Override @Nullable public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); // Check manually registered singletons. Object beanInstance = getSingleton(beanName, false); if (beanInstance != null && beanInstance.getClass() != NullBean.class) { if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { return getTypeForFactoryBean((FactoryBean<?>) beanInstance); } else { return beanInstance.getClass(); } } // No singleton instance found -> check bean definition. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // No bean definition found in this factory -> delegate to parent. return parentBeanFactory.getType(originalBeanName(name)); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Check decorated bean definition, if any: We assume it'll be easier // to determine the decorated bean's type than the proxy's type. BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd); Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd); if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { return targetClass; } } Class<?> beanClass = predictBeanType(beanName, mbd); // Check bean class whether we're dealing with a FactoryBean. if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { if (!BeanFactoryUtils.isFactoryDereference(name)) { // If it's a FactoryBean, we want to look at what it creates, not at the factory class. return getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve(); } else { return beanClass; } } else { return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null); } } @Override public String[] getAliases(String name) { String beanName = transformedBeanName(name); List<String> aliases = new ArrayList<>(); boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX); String fullBeanName = beanName; if (factoryPrefix) { fullBeanName = FACTORY_BEAN_PREFIX + beanName; } if (!fullBeanName.equals(name)) { aliases.add(fullBeanName); } String[] retrievedAliases = super.getAliases(beanName); String prefix = factoryPrefix ? FACTORY_BEAN_PREFIX : ""; for (String retrievedAlias : retrievedAliases) { String alias = prefix + retrievedAlias; if (!alias.equals(name)) { aliases.add(alias); } } if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) { BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null) { aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName))); } } return StringUtils.toStringArray(aliases); } //--------------------------------------------------------------------- // Implementation of HierarchicalBeanFactory interface //--------------------------------------------------------------------- @Override @Nullable public BeanFactory getParentBeanFactory() { return this.parentBeanFactory; } @Override public boolean containsLocalBean(String name) { String beanName = transformedBeanName(name); return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) && (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName))); } //--------------------------------------------------------------------- // Implementation of ConfigurableBeanFactory interface //--------------------------------------------------------------------- @Override public void setParentBeanFactory(@Nullable BeanFactory parentBeanFactory) { if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) { throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory); } if (this == parentBeanFactory) { throw new IllegalStateException("Cannot set parent bean factory to self"); } this.parentBeanFactory = parentBeanFactory; } @Override public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) { this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader()); } @Override @Nullable public ClassLoader getBeanClassLoader() { return this.beanClassLoader; } @Override public void setTempClassLoader(@Nullable ClassLoader tempClassLoader) { this.tempClassLoader = tempClassLoader; } @Override @Nullable public ClassLoader getTempClassLoader() { return this.tempClassLoader; } @Override public void setCacheBeanMetadata(boolean cacheBeanMetadata) { this.cacheBeanMetadata = cacheBeanMetadata; } @Override public boolean isCacheBeanMetadata() { return this.cacheBeanMetadata; } @Override public void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver) { this.beanExpressionResolver = resolver; } @Override @Nullable public BeanExpressionResolver getBeanExpressionResolver() { return this.beanExpressionResolver; } @Override public void setConversionService(@Nullable ConversionService conversionService) { this.conversionService = conversionService; } @Override @Nullable public ConversionService getConversionService() { return this.conversionService; } @Override public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) { Assert.notNull(registrar, "PropertyEditorRegistrar must not be null"); this.propertyEditorRegistrars.add(registrar); } /** * Return the set of PropertyEditorRegistrars. */ public Set<PropertyEditorRegistrar> getPropertyEditorRegistrars() { return this.propertyEditorRegistrars; } @Override public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) { Assert.notNull(requiredType, "Required type must not be null"); Assert.notNull(propertyEditorClass, "PropertyEditor class must not be null"); this.customEditors.put(requiredType, propertyEditorClass); } @Override public void copyRegisteredEditorsTo(PropertyEditorRegistry registry) { registerCustomEditors(registry); } /** * Return the map of custom editors, with Classes as keys and PropertyEditor classes as values. */ public Map<Class<?>, Class<? extends PropertyEditor>> getCustomEditors() { return this.customEditors; } @Override public void setTypeConverter(TypeConverter typeConverter) { this.typeConverter = typeConverter; } /** * Return the custom TypeConverter to use, if any. * @return the custom TypeConverter, or {@code null} if none specified */ @Nullable protected TypeConverter getCustomTypeConverter() { return this.typeConverter; } @Override public TypeConverter getTypeConverter() { TypeConverter customConverter = getCustomTypeConverter(); if (customConverter != null) { return customConverter; } else { // Build default TypeConverter, registering custom editors. SimpleTypeConverter typeConverter = new SimpleTypeConverter(); typeConverter.setConversionService(getConversionService()); registerCustomEditors(typeConverter); return typeConverter; } } @Override public void addEmbeddedValueResolver(StringValueResolver valueResolver) { Assert.notNull(valueResolver, "StringValueResolver must not be null"); this.embeddedValueResolvers.add(valueResolver); } @Override public boolean hasEmbeddedValueResolver() { return !this.embeddedValueResolvers.isEmpty(); } @Override @Nullable public String resolveEmbeddedValue(@Nullable String value) { if (value == null) { return null; } String result = value; for (StringValueResolver resolver : this.embeddedValueResolvers) { result = resolver.resolveStringValue(result); if (result == null) { return null; } } return result; } @Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); // Remove from old position, if any this.beanPostProcessors.remove(beanPostProcessor); // Track whether it is instantiation/destruction aware if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } // Add to end of list this.beanPostProcessors.add(beanPostProcessor); } @Override public int getBeanPostProcessorCount() { return this.beanPostProcessors.size(); } /** * Return the list of BeanPostProcessors that will get applied * to beans created with this factory. */ public List<BeanPostProcessor> getBeanPostProcessors() { return this.beanPostProcessors; } /** * Return whether this factory holds a InstantiationAwareBeanPostProcessor * that will get applied to singleton beans on creation. * @see #addBeanPostProcessor * @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor */ protected boolean hasInstantiationAwareBeanPostProcessors() { return this.hasInstantiationAwareBeanPostProcessors; } /** * Return whether this factory holds a DestructionAwareBeanPostProcessor * that will get applied to singleton beans on shutdown. * @see #addBeanPostProcessor * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor */ protected boolean hasDestructionAwareBeanPostProcessors() { return this.hasDestructionAwareBeanPostProcessors; } @Override public void registerScope(String scopeName, Scope scope) { Assert.notNull(scopeName, "Scope identifier must not be null"); Assert.notNull(scope, "Scope must not be null"); if (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) { throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'"); } Scope previous = this.scopes.put(scopeName, scope); if (previous != null && previous != scope) { if (logger.isDebugEnabled()) { logger.debug("Replacing scope '" + scopeName + "' from [" + previous + "] to [" + scope + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Registering scope '" + scopeName + "' with implementation [" + scope + "]"); } } } @Override public String[] getRegisteredScopeNames() { return StringUtils.toStringArray(this.scopes.keySet()); } @Override @Nullable public Scope getRegisteredScope(String scopeName) { Assert.notNull(scopeName, "Scope identifier must not be null"); return this.scopes.get(scopeName); } /** * Set the security context provider for this bean factory. If a security manager * is set, interaction with the user code will be executed using the privileged * of the provided security context. */ public void setSecurityContextProvider(SecurityContextProvider securityProvider) { this.securityContextProvider = securityProvider; } /** * Delegate the creation of the access control context to the * {@link #setSecurityContextProvider SecurityContextProvider}. */ @Override public AccessControlContext getAccessControlContext() { return (this.securityContextProvider != null ? this.securityContextProvider.getAccessControlContext() : AccessController.getContext()); } @Override public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) { Assert.notNull(otherFactory, "BeanFactory must not be null"); setBeanClassLoader(otherFactory.getBeanClassLoader()); setCacheBeanMetadata(otherFactory.isCacheBeanMetadata()); setBeanExpressionResolver(otherFactory.getBeanExpressionResolver()); setConversionService(otherFactory.getConversionService()); if (otherFactory instanceof org.springframework.beans.factory.support.AbstractBeanFactory) { org.springframework.beans.factory.support.AbstractBeanFactory otherAbstractFactory = (org.springframework.beans.factory.support.AbstractBeanFactory) otherFactory; this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars); this.customEditors.putAll(otherAbstractFactory.customEditors); this.typeConverter = otherAbstractFactory.typeConverter; this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors); this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors || otherAbstractFactory.hasInstantiationAwareBeanPostProcessors; this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors || otherAbstractFactory.hasDestructionAwareBeanPostProcessors; this.scopes.putAll(otherAbstractFactory.scopes); this.securityContextProvider = otherAbstractFactory.securityContextProvider; } else { setTypeConverter(otherFactory.getTypeConverter()); String[] otherScopeNames = otherFactory.getRegisteredScopeNames(); for (String scopeName : otherScopeNames) { this.scopes.put(scopeName, otherFactory.getRegisteredScope(scopeName)); } } } /** * Return a 'merged' BeanDefinition for the given bean name, * merging a child bean definition with its parent if necessary. * <p>This {@code getMergedBeanDefinition} considers bean definition * in ancestors as well. * @param name the name of the bean to retrieve the merged definition for * (may be an alias) * @return a (potentially merged) RootBeanDefinition for the given bean * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @throws BeanDefinitionStoreException in case of an invalid bean definition */ @Override public BeanDefinition getMergedBeanDefinition(String name) throws BeansException { String beanName = transformedBeanName(name); // Efficiently check whether bean definition exists in this factory. if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName); } // Resolve merged bean definition locally. return getMergedLocalBeanDefinition(beanName); } @Override public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); Object beanInstance = getSingleton(beanName, false); if (beanInstance != null) { return (beanInstance instanceof FactoryBean); } // No singleton instance found -> check bean definition. if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { // No bean definition found in this factory -> delegate to parent. return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name); } return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName)); } @Override public boolean isActuallyInCreation(String beanName) { return (isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName)); } /** * Return whether the specified prototype bean is currently in creation * (within the current thread). * @param beanName the name of the bean */ protected boolean isPrototypeCurrentlyInCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); return (curVal != null && (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName)))); } /** * Callback before prototype creation. * <p>The default implementation register the prototype as currently in creation. * @param beanName the name of the prototype about to be created * @see #isPrototypeCurrentlyInCreation */ @SuppressWarnings("unchecked") protected void beforePrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal == null) { this.prototypesCurrentlyInCreation.set(beanName); } else if (curVal instanceof String) { Set<String> beanNameSet = new HashSet<>(2); beanNameSet.add((String) curVal); beanNameSet.add(beanName); this.prototypesCurrentlyInCreation.set(beanNameSet); } else { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.add(beanName); } } /** * Callback after prototype creation. * <p>The default implementation marks the prototype as not in creation anymore. * @param beanName the name of the prototype that has been created * @see #isPrototypeCurrentlyInCreation */ @SuppressWarnings("unchecked") protected void afterPrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal instanceof String) { this.prototypesCurrentlyInCreation.remove(); } else if (curVal instanceof Set) { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { this.prototypesCurrentlyInCreation.remove(); } } } @Override public void destroyBean(String beanName, Object beanInstance) { destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName)); } /** * Destroy the given bean instance (usually a prototype instance * obtained from this factory) according to the given bean definition. * @param beanName the name of the bean definition * @param bean the bean instance to destroy * @param mbd the merged bean definition */ protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) { new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy(); } @Override public void destroyScopedBean(String beanName) { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); if (mbd.isSingleton() || mbd.isPrototype()) { throw new IllegalArgumentException( "Bean name '" + beanName + "' does not correspond to an object in a mutable scope"); } String scopeName = mbd.getScope(); Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope SPI registered for scope name '" + scopeName + "'"); } Object bean = scope.remove(beanName); if (bean != null) { destroyBean(beanName, bean, mbd); } } //--------------------------------------------------------------------- // Implementation methods //--------------------------------------------------------------------- /** * Return the bean name, stripping out the factory dereference prefix if necessary, * and resolving aliases to canonical names. * @param name the user-specified name * @return the transformed bean name */ //返回bean名称,如果有工厂bean的应用前缀("&"),则去掉;同时,解析别名,得到标准名称(正真名称) protected String transformedBeanName(String name) { return canonicalName(BeanFactoryUtils.transformedBeanName(name)); } /** * Determine the original bean name, resolving locally defined aliases to canonical names. * @param name the user-specified name * @return the original bean name */ //确认原始名称 protected String originalBeanName(String name) { String beanName = transformedBeanName(name); if (name.startsWith(FACTORY_BEAN_PREFIX)) { //带工厂bean的前缀,就最多只保留一个 beanName = FACTORY_BEAN_PREFIX + beanName; } return beanName; } /** * Initialize the given BeanWrapper with the custom editors registered * with this factory. To be called for BeanWrappers that will create * and populate bean instances. * <p>The default implementation delegates to {@link #registerCustomEditors}. * Can be overridden in subclasses. * @param bw the BeanWrapper to initialize */ protected void initBeanWrapper(BeanWrapper bw) { bw.setConversionService(getConversionService()); registerCustomEditors(bw); } /** * Initialize the given PropertyEditorRegistry with the custom editors * that have been registered with this BeanFactory. * <p>To be called for BeanWrappers that will create and populate bean * instances, and for SimpleTypeConverter used for constructor argument * and factory method type conversion. * @param registry the PropertyEditorRegistry to initialize */ protected void registerCustomEditors(PropertyEditorRegistry registry) { PropertyEditorRegistrySupport registrySupport = (registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null); if (registrySupport != null) { registrySupport.useConfigValueEditors(); } if (!this.propertyEditorRegistrars.isEmpty()) { for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) { try { registrar.registerCustomEditors(registry); } catch (BeanCreationException ex) { Throwable rootCause = ex.getMostSpecificCause(); if (rootCause instanceof BeanCurrentlyInCreationException) { BeanCreationException bce = (BeanCreationException) rootCause; String bceBeanName = bce.getBeanName(); if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) { if (logger.isDebugEnabled()) { logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() + "] failed because it tried to obtain currently created bean '" + ex.getBeanName() + "': " + ex.getMessage()); } onSuppressedException(ex); continue; } } throw ex; } } } if (!this.customEditors.isEmpty()) { this.customEditors.forEach((requiredType, editorClass) -> registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass))); } } /** * Return a merged RootBeanDefinition, traversing the parent bean definition * if the specified bean corresponds to a child bean definition. * @param beanName the name of the bean to retrieve the merged definition for * @return a (potentially merged) RootBeanDefinition for the given bean * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @throws BeanDefinitionStoreException in case of an invalid bean definition */ // 遍历父的bean定义信息,得到一个合并后的本地bean定义信息 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null && !mbd.stale) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } /** * Return a RootBeanDefinition for the given top-level 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) * @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) throws BeanDefinitionStoreException { return getMergedBeanDefinition(beanName, bd, null); } /** * 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 */ //得到一个合并后的bean定义信息 (通过合并父的) protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException { synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; RootBeanDefinition previous = 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 || mbd.stale) { previous = mbd; //没有父的bean定义信息 (parentName) 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. // 我自身是子,需要合并父的bean定义信息 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 { //不是可配置的bean工厂,是不允许合并bean定义的 throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without a ConfigurableBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); } // Deep copy with overridden values. mbd = new RootBeanDefinition(pbd); mbd.overrideFrom(bd); } // Set default singleton scope, if not configured before. //没有配置,就是单例 if (!StringUtils.hasLength(mbd.getScope())) { mbd.setScope(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); } } if (previous != null) { //原先有的bean定义信息,再拷贝过来 copyRelevantMergedBeanDefinitionCaches(previous, mbd); } return mbd; } } private void copyRelevantMergedBeanDefinitionCaches(RootBeanDefinition previous, RootBeanDefinition mbd) { if (ObjectUtils.nullSafeEquals(mbd.getBeanClassName(), previous.getBeanClassName()) && ObjectUtils.nullSafeEquals(mbd.getFactoryBeanName(), previous.getFactoryBeanName()) && ObjectUtils.nullSafeEquals(mbd.getFactoryMethodName(), previous.getFactoryMethodName())) { ResolvableType targetType = mbd.targetType; ResolvableType previousTargetType = previous.targetType; if (targetType == null || targetType.equals(previousTargetType)) { mbd.targetType = previousTargetType; mbd.isFactoryBean = previous.isFactoryBean; mbd.resolvedTargetType = previous.resolvedTargetType; mbd.factoryMethodReturnType = previous.factoryMethodReturnType; mbd.factoryMethodToIntrospect = previous.factoryMethodToIntrospect; } } } /** * Check the given merged bean definition, * potentially throwing validation exceptions. * @param mbd the merged bean definition to check * @param beanName the name of the bean * @param args the arguments for bean creation, if any * @throws BeanDefinitionStoreException in case of validation failure */ //如果合并后的bean定义信息是抽象的,报错 BeanIsAbstractException protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args) throws BeanDefinitionStoreException { if (mbd.isAbstract()) { throw new BeanIsAbstractException(beanName); } } /** * Remove the merged bean definition for the specified bean, * recreating it on next access. * @param beanName the bean name to clear the merged definition for */ protected void clearMergedBeanDefinition(String beanName) { RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName); if (bd != null) { bd.stale = true; } } /** * Clear the merged bean definition cache, removing entries for beans * which are not considered eligible for full metadata caching yet. * <p>Typically triggered after changes to the original bean definitions, * e.g. after applying a {@code BeanFactoryPostProcessor}. Note that metadata * for beans which have already been created at this point will be kept around. * @since 4.2 */ public void clearMetadataCache() { this.mergedBeanDefinitions.forEach((beanName, bd) -> { if (!isBeanEligibleForMetadataCaching(beanName)) { bd.stale = true; } }); } /** * Resolve the bean class for the specified bean definition, * resolving a bean class name into a Class reference (if necessary) * and storing the resolved Class in the bean definition for further use. * @param mbd the merged bean definition to determine the class for * @param beanName the name of the bean (for error handling purposes) * @param typesToMatch the types to match in case of internal type matching purposes * (also signals that the returned {@code Class} will never be exposed to application code) * @return the resolved bean class (or {@code null} if none) * @throws CannotLoadBeanClassException if we failed to load the class */ @Nullable protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch) throws CannotLoadBeanClassException { try { if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } if (System.getSecurityManager() != null) { return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext()); } else { return doResolveBeanClass(mbd, typesToMatch); } } catch (PrivilegedActionException pae) { ClassNotFoundException ex = (ClassNotFoundException) pae.getException(); throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (LinkageError err) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); } } @Nullable private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException { ClassLoader beanClassLoader = getBeanClassLoader(); ClassLoader dynamicLoader = beanClassLoader; boolean freshResolve = false; if (!ObjectUtils.isEmpty(typesToMatch)) { // When just doing type checks (i.e. not creating an actual instance yet), // use the specified temporary class loader (e.g. in a weaving scenario). ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { dynamicLoader = tempClassLoader; freshResolve = true; if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class<?> typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } } } } String className = mbd.getBeanClassName(); if (className != null) { Object evaluated = evaluateBeanDefinitionString(className, mbd); if (!className.equals(evaluated)) { // A dynamically resolved expression, supported as of 4.2... if (evaluated instanceof Class) { return (Class<?>) evaluated; } else if (evaluated instanceof String) { className = (String) evaluated; freshResolve = true; } else { throw new IllegalStateException("Invalid class name expression result: " + evaluated); } } if (freshResolve) { // When resolving against a temporary class loader, exit early in order // to avoid storing the resolved Class in the bean definition. if (dynamicLoader != null) { try { return dynamicLoader.loadClass(className); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex); } } } return ClassUtils.forName(className, dynamicLoader); } } // Resolve regularly, caching the result in the BeanDefinition... return mbd.resolveBeanClass(beanClassLoader); } /** * Evaluate the given String as contained in a bean definition, * potentially resolving it as an expression. * @param value the value to check * @param beanDefinition the bean definition that the value comes from * @return the resolved value * @see #setBeanExpressionResolver */ @Nullable protected Object evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition) { if (this.beanExpressionResolver == null) { return value; } Scope scope = null; if (beanDefinition != null) { String scopeName = beanDefinition.getScope(); if (scopeName != null) { scope = getRegisteredScope(scopeName); } } return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope)); } /** * Predict the eventual bean type (of the processed bean instance) for the * specified bean. Called by {@link #getType} and {@link #isTypeMatch}. * Does not need to handle FactoryBeans specifically, since it is only * supposed to operate on the raw bean type. * <p>This implementation is simplistic in that it is not able to * handle factory methods and InstantiationAwareBeanPostProcessors. * It only predicts the bean type correctly for a standard bean. * To be overridden in subclasses, applying more sophisticated type detection. * @param beanName the name of the bean * @param mbd the merged bean definition to determine the type for * @param typesToMatch the types to match in case of internal type matching purposes * (also signals that the returned {@code Class} will never be exposed to application code) * @return the type of the bean, or {@code null} if not predictable */ @Nullable protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) { Class<?> targetType = mbd.getTargetType(); if (targetType != null) { return targetType; } if (mbd.getFactoryMethodName() != null) { return null; } return resolveBeanClass(mbd, beanName, typesToMatch); } /** * Check whether the given bean is defined as a {@link FactoryBean}. * @param beanName the name of the bean * @param mbd the corresponding bean definition */ protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) { Boolean result = mbd.isFactoryBean; if (result == null) { Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class); result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType)); mbd.isFactoryBean = result; } return result; } /** * Determine the bean type for the given FactoryBean definition, as far as possible. * Only called if there is no singleton instance registered for the target bean * already. The implementation is allowed to instantiate the target factory bean if * {@code allowInit} is {@code true} and the type cannot be determined another way; * otherwise it is restricted to introspecting signatures and related metadata. * <p>If no {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE} if set on the bean definition * and {@code allowInit} is {@code true}, the default implementation will create * the FactoryBean via {@code getBean} to call its {@code getObjectType} method. * Subclasses are encouraged to optimize this, typically by inspecting the generic * signature of the factory bean class or the factory method that creates it. * If subclasses do instantiate the FactoryBean, they should consider trying the * {@code getObjectType} method without fully populating the bean. If this fails, * a full FactoryBean creation as performed by this implementation should be used * as fallback. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param allowInit if initialization of the FactoryBean is permitted if the type * cannot be determined another way * @return the type for the bean if determinable, otherwise {@code ResolvableType.NONE} * @since 5.2 * @see org.springframework.beans.factory.FactoryBean#getObjectType() * @see #getBean(String) */ protected ResolvableType getTypeForFactoryBean(String beanName, RootBeanDefinition mbd, boolean allowInit) { ResolvableType result = getTypeForFactoryBeanFromAttributes(mbd); if (result != ResolvableType.NONE) { return result; } if (allowInit && mbd.isSingleton()) { try { FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true); Class<?> objectType = getTypeForFactoryBean(factoryBean); return (objectType != null ? ResolvableType.forClass(objectType) : ResolvableType.NONE); } catch (BeanCreationException ex) { if (ex.contains(BeanCurrentlyInCreationException.class)) { logger.trace(LogMessage.format("Bean currently in creation on FactoryBean type check: %s", ex)); } else if (mbd.isLazyInit()) { logger.trace(LogMessage.format("Bean creation exception on lazy FactoryBean type check: %s", ex)); } else { logger.debug(LogMessage.format("Bean creation exception on eager FactoryBean type check: %s", ex)); } onSuppressedException(ex); } } return ResolvableType.NONE; } /** * Determine the bean type for a FactoryBean by inspecting its attributes for a * {@link FactoryBean#OBJECT_TYPE_ATTRIBUTE} value. * @param attributes the attributes to inspect * @return a {@link ResolvableType} extracted from the attributes or * {@code ResolvableType.NONE} * @since 5.2 */ ResolvableType getTypeForFactoryBeanFromAttributes(AttributeAccessor attributes) { Object attribute = attributes.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE); if (attribute instanceof ResolvableType) { return (ResolvableType) attribute; } if (attribute instanceof Class) { return ResolvableType.forClass((Class<?>) attribute); } return ResolvableType.NONE; } /** * Determine the bean type for the given FactoryBean definition, as far as possible. * Only called if there is no singleton instance registered for the target bean already. * <p>The default implementation creates the FactoryBean via {@code getBean} * to call its {@code getObjectType} method. Subclasses are encouraged to optimize * this, typically by just instantiating the FactoryBean but not populating it yet, * trying whether its {@code getObjectType} method already returns a type. * If no type found, a full FactoryBean creation as performed by this implementation * should be used as fallback. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @return the type for the bean if determinable, or {@code null} otherwise * @see org.springframework.beans.factory.FactoryBean#getObjectType() * @see #getBean(String) * @deprecated since 5.2 in favor of {@link #getTypeForFactoryBean(String, RootBeanDefinition, boolean)} */ @Nullable @Deprecated protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) { return getTypeForFactoryBean(beanName, mbd, true).resolve(); } /** * Mark the specified bean as already created (or about to be created). * <p>This allows the bean factory to optimize its caching for repeated * creation of the specified bean. * @param beanName the name of the bean */ // 标识这个bean已经被创建 protected void markBeanAsCreated(String beanName) { if (!this.alreadyCreated.contains(beanName)) { synchronized (this.mergedBeanDefinitions) { if (!this.alreadyCreated.contains(beanName)) { // Let the bean definition get re-merged now that we're actually creating // the bean... just in case some of its metadata changed in the meantime. clearMergedBeanDefinition(beanName); this.alreadyCreated.add(beanName); } } } } /** * Perform appropriate cleanup of cached metadata after bean creation failed. * @param beanName the name of the bean */ protected void cleanupAfterBeanCreationFailure(String beanName) { synchronized (this.mergedBeanDefinitions) { this.alreadyCreated.remove(beanName); } } /** * Determine whether the specified bean is eligible for having * its bean definition metadata cached. * @param beanName the name of the bean * @return {@code true} if the bean's metadata may be cached * at this point already */ protected boolean isBeanEligibleForMetadataCaching(String beanName) { return this.alreadyCreated.contains(beanName); } /** * Remove the singleton instance (if any) for the given bean name, * but only if it hasn't been used for other purposes than type checking. * @param beanName the name of the bean * @return {@code true} if actually removed, {@code false} otherwise */ protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) { if (!this.alreadyCreated.contains(beanName)) { removeSingleton(beanName); return true; } else { return false; } } /** * Check whether this factory's bean creation phase already started, * i.e. whether any bean has been marked as created in the meantime. * @since 4.2.2 * @see #markBeanAsCreated */ protected boolean hasBeanCreationStarted() { return !this.alreadyCreated.isEmpty(); } /** * Get the object for the given bean instance, either the bean * instance itself or its created object in case of a FactoryBean. * @param beanInstance the shared bean instance * @param name the name that may include factory dereference prefix * @param beanName the canonical bean name * @param mbd the merged bean definition * @return the object to expose for the bean // 为bean公开的对象 */ // 从beanInstance得到bean对象,可能是 protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. // 如果这个bean 不是一个工厂,不要让调用代码机会应用这个工厂 if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } if (mbd != null) { mbd.isFactoryBean = true; } return beanInstance; } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. // 1-实例不是工厂bean ,直接返回 if (!(beanInstance instanceof FactoryBean)) { return beanInstance; } //2-实例是一个工厂bean Object object = null; if (mbd != null) { mbd.isFactoryBean = true; } else { //从bean工厂注册器中查找对象(查缓存) object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. //是一个 工厂bean FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } //是不是合成的 boolean synthetic = (mbd != null && mbd.isSynthetic()); //(动态代理生成的,就不需要再执行后置处理器了) object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; } /** * Determine whether the given bean name is already in use within this factory, * i.e. whether there is a local bean or alias registered under this name or * an inner bean created with this name. * @param beanName the name to check */ public boolean isBeanNameInUse(String beanName) { return isAlias(beanName) || containsLocalBean(beanName) || hasDependentBean(beanName); } /** * Determine whether the given bean requires destruction on shutdown. * <p>The default implementation checks the DisposableBean interface as well as * a specified destroy method and registered DestructionAwareBeanPostProcessors. * @param bean the bean instance to check * @param mbd the corresponding bean definition * @see org.springframework.beans.factory.DisposableBean * @see AbstractBeanDefinition#getDestroyMethodName() * @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor */ protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) { return (bean.getClass() != NullBean.class && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())))); } /** * Add the given bean to the list of disposable beans in this factory, * registering its DisposableBean interface and/or the given destroy method * to be called on factory shutdown (if applicable). Only applies to singletons. * @param beanName the name of the bean * @param bean the bean instance * @param mbd the bean definition for the bean * @see RootBeanDefinition#isSingleton * @see RootBeanDefinition#getDependsOn * @see #registerDisposableBean * @see #registerDependentBean */ protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } } //--------------------------------------------------------------------- // Abstract methods to be implemented by subclasses 抽象方法,需要被子类实现的 //--------------------------------------------------------------------- /** * Check if this bean factory contains a bean definition with the given name. * Does not consider any hierarchy this factory may participate in. * Invoked by {@code containsBean} when no cached singleton instance is found. * <p>Depending on the nature of the concrete bean factory implementation, * this operation might be expensive (for example, because of directory lookups * in external registries). However, for listable bean factories, this usually * just amounts to a local hash lookup: The operation is therefore part of the * public interface there. The same implementation can serve for both this * template method and the public interface method in that case. * @param beanName the name of the bean to look for * @return if this bean factory contains a bean definition with the given name * @see #containsBean * @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition */ //是否有bean定义 protected abstract boolean containsBeanDefinition(String beanName); /** * Return the bean definition for the given bean name. * Subclasses should normally implement caching, as this method is invoked * by this class every time bean definition metadata is needed. * <p>Depending on the nature of the concrete bean factory implementation, * this operation might be expensive (for example, because of directory lookups * in external registries). However, for listable bean factories, this usually * just amounts to a local hash lookup: The operation is therefore part of the * public interface there. The same implementation can serve for both this * template method and the public interface method in that case. * @param beanName the name of the bean to find a definition for * @return the BeanDefinition for this prototype name (never {@code null}) * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * if the bean definition cannot be resolved * @throws BeansException in case of errors * @see RootBeanDefinition * @see ChildBeanDefinition * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#getBeanDefinition */ //得到bean定义 protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException; /** * Create a bean instance for the given merged bean definition (and arguments). * The bean definition will already have been merged with the parent definition * in case of a child definition. * <p>All bean retrieval methods delegate to this method for actual bean creation. * @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 */ //创建bean (具体工厂来实现创建方法) protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException; }