当前位置: 移动技术网 > IT编程>开发语言>Java > 使用 BeanDefinition 描述 Spring Bean

使用 BeanDefinition 描述 Spring Bean

2019年10月07日  | 移动技术网IT编程  | 我要评论

什么是beandefinition

在java中,一切皆对象。在jdk中使用java.lang.class来描述这个对象。

在spring中,存在bean这样一个概念,那spring又是怎么抽象bean这个概念,用什么类来描述bean这个对象呢?spring使用beandefinition来描述bean

beandefinition

beandefinition

beandefinition继承了attributeaccessorbeanmetadataelement接口。在spring中充斥着大量的各种接口,每种接口都拥有不同的能力,某个类实现了某个接口,也就相应的拥有了某种能力。

attributeaccessor

顾名思义,这是一个属性访问者,它提供了访问属性的能力。

attributeaccessor

beanmetadataelement

beanmetadataelement中只有一个方法,用来获取元数据元素的配置源对象:

public interface beanmetadataelement {
    @nullable
    object getsource();
}

beandefinition

beandefinition接口是spring对bean的抽象。

我们可以从源码中可以看出,spring是怎么描述一个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();

    /**
     * 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();

    /**
     * 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();

    /**
     * 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(@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.
     */
    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(@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
     */
    void setfactorymethodname(@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
     */
    default boolean hasconstructorargumentvalues() {
        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 values defined for this bean.
     *
     * @since 5.0.2
     */
    default boolean haspropertyvalues() {
        return !getpropertyvalues().isempty();
    }

    /**
     * set the name of the initializer method.
     *
     * @since 5.1
     */
    void setinitmethodname(@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
     */
    void setdestroymethodname(@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 with an indication of
     * the role and importance of a particular {@code beandefinition}.
     *
     * @see #role_application
     * @see #role_support
     * @see #role_infrastructure
     * @since 5.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();

    /**
     * set a human-readable description of this bean definition.
     *
     * @since 5.1
     */
    void setdescription(@nullable string description);

    /**
     * return a human-readable description of this bean definition.
     */
    @nullable
    string getdescription();


    // 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.
     *
     * @see #scope_prototype
     * @since 3.0
     */
    boolean isprototype();

    /**
     * return whether this bean is "abstract", that is, not meant to be instantiated.
     */
    boolean isabstract();

    /**
     * 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.
     * 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();
}

annotatedbeandefinition

annotatedbeandefinition 继承了beandefinition,拓展了beandefinition接口的能力:

annotatedbeandefinition

beandefinition常见实现类

  • childbeandefinition
  • rootbeandefinition
  • genericbeandefinition
  • annotatedgenericbeandefinition
  • scannedgenericbeandefinition

beandefinitionbuilder

beandefinitionbuilder是builder模式的应用。通过这个类我们可以方便的构建beandefinition的实例对象。举个例子:

@component
public class mybeandefinitionregistrypostprocessor implements beandefinitionregistrypostprocessor {

    @override
    public void postprocessbeandefinitionregistry(beandefinitionregistry registry) throws beansexception {
        beandefinition beandefinition = beandefinitionbuilder.genericbeandefinition(orderservice.class)
                //这里的属性名是根据setter方法
                .addpropertyreference("dao", "orderdao")
                .setinitmethodname("init")
                .setscope(beandefinition.scope_singleton)
                .getbeandefinition();

        registry.registerbeandefinition("orderservice", beandefinition);

    }

    @override
    public void postprocessbeanfactory(configurablelistablebeanfactory beanfactory) throws beansexception {
        //do nothing
    }
}

关于beandefinitionregistrypostprocessor,这里先简单介绍一下,详细的我们后面再说。

beandefinitionregistrypostprocessor继承了beanfactorypostprocessor接口,同时又增加了一个新的方法beandefinitionregistrypostprocessor#postprocessbeandefinitionregistry,该方法允许程序员通过代码编码的方式手动往程序中注册beandefinition

实例中的具体程序已上传到github:https://github.com/shenjianeng/spring-code-study


欢迎关注公众号:

coder小黑

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网