/** * Return the configuration source {@code Object} for this metadata element * (may be {@code null}). */ @Nullable default Object getSource(){ returnnull; }
/** * Create a new AttributeValue instance. * @param name the name of the attribute (never {@code null}) * @param value the value of the attribute (possibly before type conversion) */ publicBeanMetadataAttribute(String name, @Nullable Object value){ //将名字和值封装起来 Assert.notNull(name, "Name must not be null"); this.name = name; this.value = value; }
/** * Return the name of the attribute. */ public String getName(){ returnthis.name; }
/** * Return the value of the attribute. */ @Nullable public Object getValue(){ returnthis.value; }
/** * Set the configuration source {@code Object} for this metadata element. * <p>The exact type of the object will depend on the configuration mechanism used. */ publicvoidsetSource(@Nullable Object source){ this.source = source; }
@Override @Nullable public Object getSource(){ returnthis.source; }
/** * Set the attribute defined by {@code name} to the supplied {@code value}. * If {@code value} is {@code null}, the attribute is {@link #removeAttribute removed}. * <p>In general, users should take care to prevent overlaps with other * metadata attributes by using fully-qualified names, perhaps using * class or package names as prefix. * @param name the unique attribute key * @param value the attribute value to be attached */ voidsetAttribute(String name, @Nullable Object value);
/** * Get the value of the attribute identified by {@code name}. * Return {@code null} if the attribute doesn't exist. * @param name the unique attribute key * @return the current value of the attribute, if any */ @Nullable Object getAttribute(String name);
/** * Remove the attribute identified by {@code name} and return its value. * Return {@code null} if no attribute under {@code name} is found. * @param name the unique attribute key * @return the last value of the attribute, if any */ @Nullable Object removeAttribute(String name);
/** * Return {@code true} if the attribute identified by {@code name} exists. * Otherwise return {@code false}. * @param name the unique attribute key */ booleanhasAttribute(String name);
/** * Return the names of all attributes. */ String[] attributeNames();
/** * 名字与属性相对应 */ /** Map with String keys and Object values. */ privatefinal Map<String, Object> attributes = new LinkedHashMap<>();
//设为 null 值就是删除 @Override publicvoidsetAttribute(String name, @Nullable Object value){ Assert.notNull(name, "Name must not be null"); if (value != null) { this.attributes.put(name, value); } else { removeAttribute(name); } }
@Override @Nullable public Object getAttribute(String name){ Assert.notNull(name, "Name must not be null"); returnthis.attributes.get(name); }
@Override @Nullable public Object removeAttribute(String name){ Assert.notNull(name, "Name must not be null"); returnthis.attributes.remove(name); }
@Override publicbooleanhasAttribute(String name){ Assert.notNull(name, "Name must not be null"); returnthis.attributes.containsKey(name); }
@Override public String[] attributeNames() { return StringUtils.toStringArray(this.attributes.keySet()); }
/** * Copy the attributes from the supplied AttributeAccessor to this accessor. * @param source the AttributeAccessor to copy from */ protectedvoidcopyAttributesFrom(AttributeAccessor source){ Assert.notNull(source, "Source must not be null"); String[] attributeNames = source.attributeNames(); for (String attributeName : attributeNames) { setAttribute(attributeName, source.getAttribute(attributeName)); } }
/** * Set the configuration source {@code Object} for this metadata element. * <p>The exact type of the object will depend on the configuration mechanism used. */ publicvoidsetSource(@Nullable Object source){ this.source = source; }
@Override @Nullable public Object getSource(){ returnthis.source; }
/** * Add the given BeanMetadataAttribute to this accessor's set of attributes. * @param attribute the BeanMetadataAttribute object to register */ publicvoidaddMetadataAttribute(BeanMetadataAttribute attribute){ super.setAttribute(attribute.getName(), attribute); }
/** * Look up the given BeanMetadataAttribute in this accessor's set of attributes. * @param name the name of the attribute * @return the corresponding BeanMetadataAttribute object, * or {@code null} if no such attribute defined */ @Nullable public BeanMetadataAttribute getMetadataAttribute(String name){ return (BeanMetadataAttribute) super.getAttribute(name); }
/** * Scope identifier for the standard singleton scope: {@value}. * <p>Note that extended bean factories might support further scopes. * @see #setScope * @see ConfigurableBeanFactory#SCOPE_SINGLETON */ /** * 单例 */ String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
/** * Scope identifier for the standard prototype scope: {@value}. * <p>Note that extended bean factories might support further scopes. * @see #setScope * @see ConfigurableBeanFactory#SCOPE_PROTOTYPE */ /** * 原型 */ String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
/** * Role hint indicating that a {@code BeanDefinition} is a major part * of the application. Typically corresponds to a user-defined bean. */ /** * 角色 */ int ROLE_APPLICATION = 0;
/** * Role hint indicating that a {@code BeanDefinition} is a supporting * part of some larger configuration, typically an outer * {@link org.springframework.beans.factory.parsing.ComponentDefinition}. * {@code SUPPORT} beans are considered important enough to be aware * of when looking more closely at a particular * {@link org.springframework.beans.factory.parsing.ComponentDefinition}, * but not when looking at the overall configuration of an application. */ int ROLE_SUPPORT = 1;
/** * Role hint indicating that a {@code BeanDefinition} is providing an * entirely background role and has no relevance to the end-user. This hint is * used when registering beans that are completely part of the internal workings * of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}. */ int ROLE_INFRASTRUCTURE = 2;
// Modifiable attributes
/** * Set the name of the parent definition of this bean definition, if any. */ voidsetParentName(@Nullable String parentName);
/** * Return the name of the parent definition of this bean definition, if any. */ @Nullable String getParentName();
/** * Specify the bean class name of this bean definition. * <p>The class name can be modified during bean factory post-processing, * typically replacing the original class name with a parsed variant of it. * @see #setParentName * @see #setFactoryBeanName * @see #setFactoryMethodName */ /** * 设置bean类名字,这个可能会在后置处理器中修改,比如用了 GCLIB 代理配置类的时候就会改 */ voidsetBeanClassName(@Nullable String beanClassName);
/** * Return the current bean class name of this bean definition. * <p>Note that this does not have to be the actual class name used at runtime, in * case of a child definition overriding/inheriting the class name from its parent. * Also, this may just be the class that a factory method is called on, or it may * even be empty in case of a factory bean reference that a method is called on. * Hence, do <i>not</i> consider this to be the definitive bean type at runtime but * rather only use it for parsing purposes at the individual bean definition level. * @see #getParentName() * @see #getFactoryBeanName() * @see #getFactoryMethodName() */ @Nullable String getBeanClassName();
/** * Override the target scope of this bean, specifying a new scope name. * @see #SCOPE_SINGLETON * @see #SCOPE_PROTOTYPE */ /** * 设置范围,是单例,还是原型 */ voidsetScope(@Nullable String scope);
/** * Return the name of the current target scope for this bean, * or {@code null} if not known yet. */ @Nullable String getScope();
/** * Set whether this bean should be lazily initialized. * <p>If {@code false}, the bean will get instantiated on startup by bean * factories that perform eager initialization of singletons. */ /** * 设置是否是懒加载 */ voidsetLazyInit(boolean lazyInit);
/** * Return whether this bean should be lazily initialized, i.e. not * eagerly instantiated on startup. Only applicable to a singleton bean. */ booleanisLazyInit();
/** * Set the names of the beans that this bean depends on being initialized. * The bean factory will guarantee that these beans get initialized first. */ /** * 设置需要先加载的依赖的类名字数组 */ voidsetDependsOn(@Nullable String... dependsOn);
/** * Return the bean names that this bean depends on. */ @Nullable String[] getDependsOn();
/** * Set whether this bean is a candidate for getting autowired into some other bean. * <p>Note that this flag is designed to only affect type-based autowiring. * It does not affect explicit references by name, which will get resolved even * if the specified bean is not marked as an autowire candidate. As a consequence, * autowiring by name will nevertheless inject a bean if the name matches. */ /** * 设置是否适合给其他类做自动装配 */ voidsetAutowireCandidate(boolean autowireCandidate);
/** * Return whether this bean is a candidate for getting autowired into some other bean. */ booleanisAutowireCandidate();
/** * Set whether this bean is a primary autowire candidate. * <p>If this value is {@code true} for exactly one bean among multiple * matching candidates, it will serve as a tie-breaker. */ voidsetPrimary(boolean primary);
/** * Return whether this bean is a primary autowire candidate. */ /** * 设置是否优先自动装配 */ booleanisPrimary();
/** * Specify the factory bean to use, if any. * This the name of the bean to call the specified factory method on. * @see #setFactoryMethodName */ /** * 设置FactoryBean的名字 */ voidsetFactoryBeanName(@Nullable String factoryBeanName);
/** * Return the factory bean name, if any. */ @Nullable String getFactoryBeanName();
/** * Specify a factory method, if any. This method will be invoked with * constructor arguments, or with no arguments if none are specified. * The method will be invoked on the specified factory bean, if any, * or otherwise as a static method on the local bean class. * @see #setFactoryBeanName * @see #setBeanClassName */ voidsetFactoryMethodName(@Nullable String factoryMethodName);
/** * Return a factory method, if any. */ @Nullable String getFactoryMethodName();
/** * Return the constructor argument values for this bean. * <p>The returned instance can be modified during bean factory post-processing. * @return the ConstructorArgumentValues object (never {@code null}) */ /** * 获取构造函数的参数 */ ConstructorArgumentValues getConstructorArgumentValues();
/** * Return if there are constructor argument values defined for this bean. * @since 5.0.2 */ defaultbooleanhasConstructorArgumentValues(){ return !getConstructorArgumentValues().isEmpty(); }
/** * Return the property values to be applied to a new instance of the bean. * <p>The returned instance can be modified during bean factory post-processing. * @return the MutablePropertyValues object (never {@code null}) */ MutablePropertyValues getPropertyValues();
/** * Return if there are property values defined for this bean. * @since 5.0.2 */ defaultbooleanhasPropertyValues(){ return !getPropertyValues().isEmpty(); }
/** * Set the name of the initializer method. * @since 5.1 */ /** * 设置初始化方法 对应@PostConstruct */ voidsetInitMethodName(@Nullable String initMethodName);
/** * Return the name of the initializer method. * @since 5.1 */ @Nullable String getInitMethodName();
/** * Set the name of the destroy method. * @since 5.1 */ /** * 设置销毁时候的方法 对应@PreDestroy */ voidsetDestroyMethodName(@Nullable String destroyMethodName);
/** * Return the name of the destroy method. * @since 5.1 */ @Nullable String getDestroyMethodName();
/** * Set the role hint for this {@code BeanDefinition}. The role hint * provides the frameworks as well as tools an indication of * the role and importance of a particular {@code BeanDefinition}. * @since 5.1 * @see #ROLE_APPLICATION * @see #ROLE_SUPPORT * @see #ROLE_INFRASTRUCTURE */ voidsetRole(int role);
/** * Get the role hint for this {@code BeanDefinition}. The role hint * provides the frameworks as well as tools an indication of * the role and importance of a particular {@code BeanDefinition}. * @see #ROLE_APPLICATION * @see #ROLE_SUPPORT * @see #ROLE_INFRASTRUCTURE */ intgetRole();
/** * Set a human-readable description of this bean definition. * @since 5.1 */ voidsetDescription(@Nullable String description);
/** * Return a human-readable description of this bean definition. */ @Nullable String getDescription();
// Read-only attributes
/** * Return a resolvable type for this bean definition, * based on the bean class or other specific metadata. * <p>This is typically fully resolved on a runtime-merged bean definition * but not necessarily on a configuration-time definition instance. * @return the resolvable type (potentially {@link ResolvableType#NONE}) * @since 5.2 * @see ConfigurableBeanFactory#getMergedBeanDefinition */ ResolvableType getResolvableType();
/** * Return whether this a <b>Singleton</b>, with a single, shared instance * returned on all calls. * @see #SCOPE_SINGLETON */ booleanisSingleton();
/** * Return whether this a <b>Prototype</b>, with an independent instance * returned for each call. * @since 3.0 * @see #SCOPE_PROTOTYPE */ booleanisPrototype();
/** * Return whether this bean is "abstract", that is, not meant to be instantiated. */ booleanisAbstract();
/** * Return a description of the resource that this bean definition * came from (for the purpose of showing context in case of errors). */ @Nullable String getResourceDescription();
/** * Return the originating BeanDefinition, or {@code null} if none. * <p>Allows for retrieving the decorated bean definition, if any. * <p>Note that this method returns the immediate originator. Iterate through the * originator chain to find the original BeanDefinition as defined by the user. */ @Nullable BeanDefinition getOriginatingBeanDefinition();
/** * Obtain the annotation metadata (as well as basic class metadata) * for this bean definition's bean class. * @return the annotation metadata object (never {@code null}) */ AnnotationMetadata getMetadata();
/** * Obtain metadata for this bean definition's factory method, if any. * @return the factory method metadata, or {@code null} if none * @since 4.1.1 */ @Nullable MethodMetadata getFactoryMethodMetadata();
/** * 通过 beanClass 来获取元数据 */ /** * Create a new AnnotatedGenericBeanDefinition for the given bean class. * @param beanClass the loaded bean class */ publicAnnotatedGenericBeanDefinition(Class<?> beanClass){ setBeanClass(beanClass); this.metadata = AnnotationMetadata.introspect(beanClass); }
/** * 从注解元数据获取 beanClass */ /** * Create a new AnnotatedGenericBeanDefinition for the given annotation metadata, * allowing for ASM-based processing and avoidance of early loading of the bean class. * Note that this constructor is functionally equivalent to * {@link org.springframework.context.annotation.ScannedGenericBeanDefinition * ScannedGenericBeanDefinition}, however the semantics of the latter indicate that a * bean was discovered specifically via component-scanning as opposed to other means. * @param metadata the annotation metadata for the bean class in question * @since 3.1.1 */ publicAnnotatedGenericBeanDefinition(AnnotationMetadata metadata){ Assert.notNull(metadata, "AnnotationMetadata must not be null"); if (metadata instanceof StandardAnnotationMetadata) { setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass()); } else { setBeanClassName(metadata.getClassName()); } this.metadata = metadata; }
/** * 从注解元数据与方法元数据创建 */ /** * Create a new AnnotatedGenericBeanDefinition for the given annotation metadata, * based on an annotated class and a factory method on that class. * @param metadata the annotation metadata for the bean class in question * @param factoryMethodMetadata metadata for the selected factory method * @since 4.1.1 */ publicAnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata){ this(metadata); Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null"); setFactoryMethodName(factoryMethodMetadata.getMethodName()); this.factoryMethodMetadata = factoryMethodMetadata; }
/** * 在读/写和创建实例的方法有关的字段、缓存字段时使用此锁。 */ final Object constructorArgumentLock = new Object(); /** * 在读/写后处理器相关缓存字段时使用此锁 */ final Object postProcessingLock = new Object();
// 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; if (bd.getParentName() == null) {
// 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) { copyRelevantMergedBeanDefinitionCaches(previous, mbd); } return mbd; } }