BeanDefinition
Posted 恒奇恒毅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BeanDefinition相关的知识,希望对你有一定的参考价值。
BeanDefinition
是Spring中非常核心的概念,表示Bean定义,Spring根据BeanDefinition
来创建Bean对象,
BeanDefinition
有很多的属性用来描述Bean。
一、 BeanDefinition
定义
其类定义如下:
/**
* A BeanDefinition describes a bean instance, which has property values,
* constructor argument values, and further information supplied by
* concrete implementations.
*
* <p>This is just a minimal interface: The main intention is to allow a
* @link BeanFactoryPostProcessor such as @link PropertyPlaceholderConfigurer
* to introspect and modify property values and other bean metadata.
*
* @author Juergen Hoeller
* @author Rob Harrop
* @since 19.03.2004
* @see ConfigurableListableBeanFactory#getBeanDefinition
* @see org.springframework.beans.factory.support.RootBeanDefinition
* @see org.springframework.beans.factory.support.ChildBeanDefinition
*/
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
/**
* Scope identifier for the standard singleton scope: "singleton".
* <p>Note that extended bean factories might support further scopes.
* @see #setScope
*/
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
/**
* Scope identifier for the standard prototype scope: "prototype".
* <p>Note that extended bean factories might support further scopes.
* @see #setScope
*/
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.
*/
void setParentName(String parentName);
/**
* Return the name of the parent definition of this bean definition, if any.
*/
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
*/
void setBeanClassName(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()
*/
String getBeanClassName();
/**
* Override the target scope of this bean, specifying a new scope name.
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
void setScope(String scope);
/**
* Return the name of the current target scope for this bean,
* or @code null if not known yet.
*/
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.
*/
void setLazyInit(boolean lazyInit);
/**
* Return whether this bean should be lazily initialized, i.e. not
* eagerly instantiated on startup. Only applicable to a singleton bean.
*/
boolean isLazyInit();
/**
* Set the names of the beans that this bean depends on being initialized.
* The bean factory will guarantee that these beans get initialized first.
*/
void setDependsOn(String... dependsOn);
/**
* Return the bean names that this bean depends on.
*/
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.
*/
void setAutowireCandidate(boolean autowireCandidate);
/**
* Return whether this bean is a candidate for getting autowired into some other bean.
*/
boolean isAutowireCandidate();
/**
* 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.
*/
void setPrimary(boolean primary);
/**
* Return whether this bean is a primary autowire candidate.
*/
boolean isPrimary();
/**
* Specify the factory bean to use, if any.
* This the name of the bean to call the specified factory method on.
* @see #setFactoryMethodName
*/
void setFactoryBeanName(String factoryBeanName);
/**
* Return the factory bean name, if any.
*/
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
*/
void setFactoryMethodName(String factoryMethodName);
/**
* Return a factory method, if any.
*/
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 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();
// Read-only attributes
/**
* Return whether this a <b>Singleton</b>, with a single, shared instance
* returned on all calls.
* @see #SCOPE_SINGLETON
*/
boolean isSingleton();
/**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();
/**
* Return whether this bean is "abstract", that is, not meant to be instantiated.
*/
boolean isAbstract();
/**
* Get the role hint for this @code BeanDefinition. The role hint
* provides the frameworks as well as tools with an indication of
* the role and importance of a particular @code BeanDefinition.
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
int getRole();
/**
* Return a human-readable description of this bean definition.
*/
String getDescription();
/**
* Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
String getResourceDescription();
/**
* Return the originating BeanDefinition, or @code null if none.
* 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.
*/
BeanDefinition getOriginatingBeanDefinition();
定义了很多描述一个BeanDefinition
的属性的setter和getter方法
- parentName:父
BeanDefinition
名,一般没有,只有父子关系的BeanDefinition
才有 - beanClassName:表示一个bean的类型,比如UserService.class、OrderService.class,Spring在创建Bean的过程中会根据此属性来实例化得到对象。
- scope:表示一个bean的作用域,比如:scope等于singleton,该bean就是一个单例Bean; scope等于prototype,该bean就是一个原型Bean。
- lazyInit:表示一个bean是不是需要懒加载,prototype类型的bean的lazyInit属性不起作用。懒加载的单例bean,会在第一次getBean的时候生成该bean,非懒加载的单例bean,则会在Spring启动过程中直接生成好。
- dependsOn:表示一个bean在创建之前所依赖的其他bean,在一个bean创建之前,它所依赖的这些bean得先全部创建好。
- autowireCandidate:表示该bean是否支持自动注入候选
- primary:表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean并且没有使用
@Qulifier
指定,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean注入给属性。 - factoryBeanName:工厂Bean名字,标注@Configuration的类
- factoryMethodName:工厂Bean方法名字,以上两者来自@Bean注解的
- constructorArgumentValues(ConstructorArgumentValues):构造方法参数值
- propertyValues(MutablePropertyValues):所有的属性值
- initMethodName:表示一个bean的初始化方法,一个bean的生命周期过程中有一个步骤叫初始化,Spring会在这个步骤中去调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工。
其类继承层次如下:
二、AttributeAccessor
BeanDefinition
继承自AttributeAccessor
,定义了属性获取和设置的方法,其基本实现AttributeAccessorSupport
采用map。进一步的BeanMetadataAttributeAccessor
采用BeanMetadataAttribute
来包装了value。
public interface AttributeAccessor
/**
* 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
*/
void setAttribute(String name, 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
*/
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
*/
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
*/
boolean hasAttribute(String name);
/**
* Return the names of all attributes.
*/
String[] attributeNames();
三、AbstractBeanDefinition
AbstractBeanDefinition
是BeanDefinition
的基础实现,定义了一系列的属性,并提供了getter/setter方法。具体的BeanDefinition
实现(RootBeanDefinition
、ChildBeanDefinition
、GenericBeanDefinition
)都继承自该类。
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable
private volatile Object beanClass;
private String scope = SCOPE_DEFAULT;
private boolean abstractFlag = false;
private boolean lazyInit = false;
private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private String[] dependsOn;
private boolean autowireCandidate = true;
private boolean primary = false;
private final Map<String, AutowireCandidateQualifier> qualifiers =
new LinkedHashMap<String, AutowireCandidateQualifier>(0);
private boolean nonPublicAccessAllowed = true;
private boolean lenientConstructorResolution = true;
private String factoryBeanName;
private String factoryMethodName;
private ConstructorArgumentValues constructorArgumentValues;
private MutablePropertyValues propertyValues;
private MethodOverrides methodOverrides = new MethodOverrides();
private String initMethodName;
private String destroyMethodName;
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
private boolean synthetic = false;
private int role = BeanDefinition.ROLE_APPLICATION;
private String description;
private Resource resource;
。。。
四、RootBeanDefinition
、ChildBeanDefinition
、GenericBeanDefinition
RootBeanDefinition
代表普通的BeanDefinition
实现,通过其构造方法直接new BeanDefinition
。ChildBeanDefinition
代表可以设置父BeanDefinition
的。
GenericBeanDefinition
代表一般的BeanDefinition
,主要的两种实现AnnotatedGenericBeanDefinition
和ScannedGenericBeanDefinition
都继承自他。
五、AnnotatedBeanDefinition
AnnotatedBeanDefinition
表示注解的BeanDefinition
,有两种主要的实现AnnotatedGenericBeanDefinition
和ScannedGenericBeanDefinition
public interface AnnotatedBeanDefinition extends BeanDefinition
/**
* 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
*/
MethodMetadata getFactoryMethodMetadata();
六、AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition
继承自GenericBeanDefinition
,扩展了注解类的元信息和工厂方法元信息
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition
private final AnnotationMetadata metadata;
private MethodMetadata factoryMethodMetadata;
/**
* Create a new AnnotatedGenericBeanDefinition for the given bean class.
* @param beanClass the loaded bean class
*/
public AnnotatedGenericBeanDefinition(Class<?> beanClass)
setBeanClass(beanClass);
this.metadata = new StandardAnnotationMetadata(beanClass, true);
/**
* 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
*/
public AnnotatedGenericBeanDefinition(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
*/
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata)
this(metadata);
Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null");
setFactoryMethodName(factoryMethodMetadata.getMethodName());
this.factoryMethodMetadata = factoryMethodMetadata;
@Override
public final AnnotationMetadata getMetadata()
return this.metadata;
@Override
public final MethodMetadata getFactoryMethodMetadata()
return this.factoryMethodMetadata;
七、ScannedGenericBeanDefinition
该类代表扫描的BeanDefinition
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition
private final AnnotationMetadata metadata;
/**
* Create a new ScannedGenericBeanDefinition for the class that the
* given MetadataReader describes.
* @param metadataReader the MetadataReader for the scanned target class
*/
public ScannedGenericBeanDefinition(MetadataReader metadataReader)
Assert.notNull(metadataReader, "MetadataReader must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
setBeanClassName(this.metadata.getClassName());
@Override
public final AnnotationMetadata getMetadata()
return this.metadata;
@Override
public MethodMetadata getFactoryMethodMetadata()
return null;
八、BeanDefinitionBuilder
BeanDefinitionBuilder
通过建造者模式提供了方便生成和设置属性的BeanDefinition
的方法。我们常常用它来生成RootBeanDefinition
、ChildBeanDefinition
、GenericBeanDefinition
。
public class BeanDefinitionBuilder
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link GenericBeanDefinition.
*/
public static BeanDefinitionBuilder genericBeanDefinition()
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new GenericBeanDefinition();
return builder;
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link GenericBeanDefinition.
* @param beanClass the @code Class of the bean that the definition is being created for
*/
public static BeanDefinitionBuilder genericBeanDefinition(Class<?> beanClass)
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new GenericBeanDefinition();
builder.beanDefinition.setBeanClass(beanClass);
return builder;
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link GenericBeanDefinition.
* @param beanClassName the class name for the bean that the definition is being created for
*/
public static BeanDefinitionBuilder genericBeanDefinition(String beanClassName)
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new GenericBeanDefinition();
builder.beanDefinition.setBeanClassName(beanClassName);
return builder;
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link RootBeanDefinition.
* @param beanClass the @code Class of the bean that the definition is being created for
*/
public static BeanDefinitionBuilder rootBeanDefinition(Class<?> beanClass)
return rootBeanDefinition(beanClass, null);
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link RootBeanDefinition.
* @param beanClass the @code Class of the bean that the definition is being created for
* @param factoryMethodName the name of the method to use to construct the bean instance
*/
public static BeanDefinitionBuilder rootBeanDefinition(Class<?> beanClass, String factoryMethodName)
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new RootBeanDefinition();
builder.beanDefinition.setBeanClass(beanClass);
builder.beanDefinition.setFactoryMethodName(factoryMethodName);
return builder;
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link RootBeanDefinition.
* @param beanClassName the class name for the bean that the definition is being created for
*/
public static BeanDefinitionBuilder rootBeanDefinition(String beanClassName)
return rootBeanDefinition(beanClassName, null);
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link RootBeanDefinition.
* @param beanClassName the class name for the bean that the definition is being created for
* @param factoryMethodName the name of the method to use to construct the bean instance
*/
public static BeanDefinitionBuilder rootBeanDefinition(String beanClassName, String factoryMethodName)
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new RootBeanDefinition();
builder.beanDefinition.setBeanClassName(beanClassName);
builder.beanDefinition.setFactoryMethodName(factoryMethodName);
return builder;
/**
* Create a new @code BeanDefinitionBuilder used to construct a @link ChildBeanDefinition.
* @param parentName the name of the parent bean
*/
public static BeanDefinitionBuilder childBeanDefinition(String parentName)
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new ChildBeanDefinition(parentName);
return builder;
/**
* The @code BeanDefinition instance we are creating.
*/
private AbstractBeanDefinition beanDefinition;
/**
* Our current position with respect to constructor args.
*/
private int constructorArgIndex;
/**
* Enforce the use of factory methods.
*/
private BeanDefinitionBuilder()
/**
* Return the current BeanDefinition object in its raw (unvalidated) form.
* @see #getBeanDefinition()
*/
public AbstractBeanDefinition getRawBeanDefinition()
return this.beanDefinition;
/**
* Validate and return the created BeanDefinition object.
*/
public AbstractBeanDefinition getBeanDefinition()
this.beanDefinition.validate();
return this.beanDefinition;
/**
* Set the name of the parent definition of this bean definition.
*/
public BeanDefinitionBuilder setParentName(String parentName)
this.beanDefinition.setParentName(parentName);
return this;
/**
* Set the name of a static factory method to use for this definition,
* to be called on this bean's class.
*/
public BeanDefinitionBuilder setFactoryMethod(String factoryMethod)
this.beanDefinition.setFactoryMethodName(factoryMethod);
return this;
/**
* Set the name of a non-static factory method to use for this definition,
* including the bean name of the factory instance to call the method on.
* @since 4.3.6
*/
public BeanDefinitionBuilder setFactoryMethodOnBean(String factoryMethod, String factoryBean)
this.beanDefinition.setFactoryMethodName(factoryMethod);
this.beanDefinition.setFactoryBeanName(factoryBean);
return this;
/**
* Add an indexed constructor arg value. The current index is tracked internally
* and all additions are at the present point.
* @deprecated since Spring 2.5, in favor of @link #addConstructorArgValue.
* This variant just remains around for Spring Security 2.x compatibility.
*/
@Deprecated
public BeanDefinitionBuilder addConstructorArg(Object value)
return addConstructorArgValue(value);
/**
* Add an indexed constructor arg value. The current index is tracked internally
* and all additions are at the present point.
*/
public BeanDefinitionBuilder addConstructorArgValue(Object value)
this.beanDefinition.getConstructorArgumentValues(以上是关于BeanDefinition的主要内容,如果未能解决你的问题,请参考以下文章