Spring源码之IOC(一)BeanDefinition源码解析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取 2000+ 道 Java 面试题

1 概述

Bean的定义主要是由BeanDefinition来描述的。BeanDefinition是Spring中包装bean的数据结构,她描述了一个bean实例属性、构造参数。当然针对她的具体实现类提供了更加丰富的功能。这仅仅是一个基本的接口,这个接口的主要目的是允许修改和获取bean的属性和元数据。

2 类关系

针对BeanDefinition,我们首先来看一下UML类图。

20191123100232\_1.png

从上图我们可以看出BeanDefinition是一个接口,并且继承了AttributeAccessor和BeanMetadataElement这两个接口。我们来看一下这两个接口做了什么。

(1)AttributeAccessor

这个接口主要定义了一些对任意对象的元数据的访问的函数,具体的源码如下。

    public interface AttributeAccessor {

        //设置指定名称的属性为指定的内容,当然如果这个内容为null就相当于将这个属性进行了删除。
        void setAttribute(String name, @Nullable Object value);

        //获取指定名称的属性值
        @Nullable
        Object getAttribute(String name);

        //移除指定名称的属性
        @Nullable
        Object removeAttribute(String name);

        //判断对象是否有对应名称的属性
        boolean hasAttribute(String name);

        //获取所有属性名称的数组
        String[] attributeNames();
    }

(2)BeanMetadataElement

返回元数据元素的配置源对象,这个类就仅仅包含了一个getResource函数。

3 属性

(1) SCOPE_SINGLETON

这是一个bean为单列时候的一个标识符。

(2) SCOPE_PROTOTYPE

这是一个bean为非单列时候的标识服。这里针对单列和非单列简单说明一下。
单列是在整个程序运行的过程当中仅仅只有一个对应的对象被创建,比如我们常见的配置类,这在整个程序运行的过程中就只有一个。
非单列,是在每次使用类对应的bean的时候都重新创建对应的对象,当然如果类包含状态的时候我们就考虑使用非单列。

(3) ROLE_APPLICATION

表示这个bean是应用程序的主要部分。

(4) ROLE_SUPPORT

表示BeanDefinition是某些大型配置的支持部分的角色提示,通常是一个外部ComponentDefinition。当查看某个特定的ComponentDefinition时,认为bean非常重要,以便在查看应用程序的整体配置时能够意识到这一点。

(5) ROLE_INFRASTRUCTURE

表明一个BeanDefinition是提供一个完全背景的角色,并且与最终用户没有关系。这个提示用于注册完全是ComponentDefinition内部工作的一部分的bean。

4 函数

真针对函数部分的学习,我们直接查看源码部分吧,这些函数其实主要是对一些基础属性的访问器和修改器。

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

        // 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.
         */
        @Nullable
        String getDescription();

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

利用注释我们可以理解每个函数的具体作用,我们这里就不进行一一解释了。

通过上面的分析,我们对BeanDefinition有了个深入的认识,接下来我们会对BeanDefinition的子类进行详细分析,欢迎交流。


来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring源码之IOC(一)BeanDefinition源码解析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏