What is a BeanDefinition
In Java, everything is an object. The java.lang.Class is used in the JDK to describe the Class object.
In Spring, there is such a concept as bean. How does Spring abstract the concept of bean? What class is used to describe the bean object? Spring uses beanDefinitions to describe beans.
BeanDefinition
BeanDefinition inherits AttributeAccessor and BeanMetadataElement interfaces. Spring is full of interfaces, each with different capabilities, and a class that implements an interface has corresponding capabilities.
AttributeAccessor
As the name implies, this is a property visitor that provides the ability to access properties.
BeanMetadataElement
There is only one method in the BeanMetadataElement to get the metadata element’s configuration source object:
public interface BeanMetadataElement {
@Nullable
Object getSource(a);
}
Copy the code
BeanDefinition
The BeanDefinition interface is Spring’s abstraction of beans.
We can see from the source code how Spring describes a bean:
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(@Nullable String parentName);
/** * Return the name of the parent definition of this bean definition, if any. */
@Nullable
String getParentName(a);
/**
* 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(@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(a);
/**
* Override the target scope of this bean, specifying a new scope name.
*
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
void setScope(@Nullable String scope);
/**
* Return the name of the current target scope for this bean,
* or {@code null} if not known yet.
*/
@Nullable
String getScope(a);
/**
* 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(a);
/** * 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(@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. * 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(a);
/**
* 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(a);
/**
* 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(@Nullable String factoryBeanName);
/** * Return the factory bean name, if any. */
@Nullable
String getFactoryBeanName(a);
/**
* 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(@Nullable String factoryMethodName);
/** * Return a factory method, if any. */
@Nullable
String getFactoryMethodName(a);
/**
* 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(a);
/**
* Return if there are constructor argument values defined for this bean.
*
* @since5.0.2 * /
default boolean hasConstructorArgumentValues(a) {
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(a);
/**
* Return if there are property values values defined for this bean.
*
* @since5.0.2 * /
default boolean hasPropertyValues(a) {
return! getPropertyValues().isEmpty(); }/**
* Set the name of the initializer method.
*
* @since5.1 * /
void setInitMethodName(@Nullable String initMethodName);
/**
* Return the name of the initializer method.
*
* @since5.1 * /
@Nullable
String getInitMethodName(a);
/**
* Set the name of the destroy method.
*
* @since5.1 * /
void setDestroyMethodName(@Nullable String destroyMethodName);
/**
* Return the name of the destroy method.
*
* @since5.1 * /
@Nullable
String getDestroyMethodName(a);
/**
* Set 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
* @since5.1 * /
void setRole(int role);
/**
* 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(a);
/**
* Set a human-readable description of this bean definition.
*
* @since5.1 * /
void setDescription(@Nullable String description);
/** * Return a human-readable description of this bean definition. */
@Nullable
String getDescription(a);
// Read-only attributes
/**
* Return whether this a <b>Singleton</b>, with a single, shared instance
* returned on all calls.
*
* @see #SCOPE_SINGLETON
*/
boolean isSingleton(a);
/**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
*
* @see #SCOPE_PROTOTYPE
* @since3.0 * /
boolean isPrototype(a);
/** * Return whether this bean is "abstract", that is, not meant to be instantiated. */
boolean isAbstract(a);
/** * 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(a);
/**
* 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.
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition(a);
}
Copy the code
AnnotatedBeanDefinition
AnnotatedBeanDefinition inherits BeanDefinition and expands the capabilities of the BeanDefinition interface:
BeanDefinition common implementation class
- ChildBeanDefinition
- RootBeanDefinition
- GenericBeanDefinition
- AnnotatedGenericBeanDefinition
- ScannedGenericBeanDefinition
BeanDefinitionBuilder
BeanDefinitionBuilder is an application of the Builder pattern. This class makes it easy to build instance objects of BeanDefinition. Here’s an example:
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(OrderService.class)
// The property name here is based on the setter method
.addPropertyReference("dao"."orderDao")
.setInitMethodName("init")
.setScope(BeanDefinition.SCOPE_SINGLETON)
.getBeanDefinition();
registry.registerBeanDefinition("orderService", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//do nothing}}Copy the code
About BeanDefinitionRegistryPostProcessor, first make a brief introduction here, detailed behind us.
BeanDefinitionRegistryPostProcessor inherited spring BeanFactoryPostProcessor interface, And added a new method of BeanDefinitionRegistryPostProcessor# postProcessBeanDefinitionRegistry, This method allows a programmer to register a BeanDefinition manually in a program by code.
The specific program in the instance has been uploaded to github: github.com/shenjianeng…
Welcome to pay attention to the public account, we learn and grow together.