3. La interfaz principal de BeanDefinition

El último libro habló sobre los conceptos básicos de BeanDefinition.En este artículo, discutimos el sistema de la familia BeanDefinition en detalle. Antes de explicar, el autor ofreció una vez más el diagrama de relaciones de herencia familiar de BeanDefinition:

imagen.png

    
    /***
    BeanDefinition接口的父接口:
    
     1. AttributeAccessor
             1.1 实现类 AttributeAccessorSupport 作用是操作bd的属性,属性存放在LinkedHashMap。
             
     2. BeanMetadataElement
             2.1 实现类 BeanMetadataAttributeAccessor获取源即bd对应的class的磁盘文件位置
             2.2 实现类 BeanMetadataAttributeAccessor继承了AttributeAccessorSupport既可以操作属性值,也可以操作源
             2.3 属性封装对象 BeanMetadataAttribute
            
     ***/     
     
  public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement    

1. La interfaz principal de BeanDefinition

La publicación de blog anterior detalló las funciones de la interfaz BeanDefinition, y el autor tiene la intención de ampliar esta interfaz.

Primero mire la interfaz principal de BeanDefinition:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement

La interfaz BeanDefinition hereda las dos interfaces de AttributeAccessor y BeanMetadataElement.

Es decir, la clase de implementación de BeanDefinition realiza al mismo tiempo

Las funciones de las tres interfaces BeanDefinition, AttributeAccessor y BeanMetadataElement.

1.1 AttributeAccessor: rol operación bd atributo

    /**
     *定义用于附加和访问BeanDefinition元数据的通用的接口,来自任意对象
     */
    public interface AttributeAccessor {
        /**
        将属性名为name的属性的属性值设置为value
        注意是BeanDefinition的属性
        */
        void setAttribute(String name, Object value);
        /**
       获取指定name的属性值,如果该属性不存在,则返回Null
       注意是BeanDefinition的属性
       */
        Object getAttribute(String name);
        /**
       删除指定name的属性值,如果找不到Nmae属性的值则返回Null
       注意是BeanDefinition的属性
       */
        Object removeAttribute(String name);
        /**
       如果属性名为name的属性存在则返回true,否者返回false
       注意是BeanDefinition的属性
       */
        boolean hasAttribute(String name);
        /**
       返回所有的属性名称
       注意是BeanDefinition的属性
         */
        String[] attributeNames();
    }

La definición de la interfaz se usa para adjuntar y acceder a los metadatos de BeanDefinition. Sabemos que la interfaz solo define el método de operación. El método de esta interfaz es muy simple, pero no podemos ver lo que significa esta interfaz. Mirando hacia atrás en el diagrama de herencia, podemos encontrar esta interfaz La única clase de implementación AttributeAccessorSupport:

1.1.1 Clase de implementación AttributeAccessorSupport

    public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {

        /** Map with String keys and Object values. */
        //用于存放属性键值对
        private final Map<String, Object> attributes = new LinkedHashMap<>();
        
        //设置属性值 value是BeanMetadataAttribute类型
        @Override 
        public void setAttribute(String name, @Nullable Object value) {
            Assert.notNull(name, "Name must not be null");
            if (value != null) {
                this.attributes.put(name, value);
            }
            else {
                removeAttribute(name);
            }
        }
        
        //获取属性值 value是BeanMetadataAttribute类型
        @Override
        @Nullable
        public Object getAttribute(String name) {
            Assert.notNull(name, "Name must not be null");
            return this.attributes.get(name);
        }
        
        //删除属性值
        @Override
        @Nullable
        public Object removeAttribute(String name) {
            Assert.notNull(name, "Name must not be null");
            return this.attributes.remove(name);
        }
       
       //判断是否有属性值
        @Override
        public boolean hasAttribute(String name) {
            Assert.notNull(name, "Name must not be null");
            return this.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
         */
        protected void copyAttributesFrom(AttributeAccessor source) {
            Assert.notNull(source, "Source must not be null");
            String[] attributeNames = source.attributeNames();
            for (String attributeName : attributeNames) {
                setAttribute(attributeName, source.getAttribute(attributeName));
            }
        }
        
        //重写equals方法,判断是否与别的属性类共用一个存储结构,即判断LinkedHashMap是否相等
        @Override
        public boolean equals(Object other) {
            return (this == other || (other instanceof AttributeAccessorSupport &&
                    this.attributes.equals(((AttributeAccessorSupport) other).attributes)));
        }
        @Override
        public int hashCode() {
            return this.attributes.hashCode();
        }
    }

De hecho, todavía no podemos ver la relación entre esta clase de implementación y BeanDefinition. Pero dejemos en claro que AttributeAccessorSupport solo mantiene un LinkedHashMap. Algunos valores de atributos de BeanDefinition se almacenan en este LinkedHashMap. ¿Qué valores de atributos son? Mira el código a continuación:

        public class SpringTest {
            public static void main(String[] args) throws InterruptedException {
                AnnotationConfigApplicationContext context = new    
                                            AnnotationConfigApplicationContext();
                //注册配置类
                context.register(Config.class);
                GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
                beanDefinition.setBeanClassName("com.InterService");
                //设置属性值
                beanDefinition.setAttribute("AttributeAccessor","源码之路");
                //将beanDefinition注册到spring容器中
                context.registerBeanDefinition("interService",beanDefinition);
                //加载或者刷新当前的配置信息
                context.refresh();
                //拿到属性信息
                String[] attributes = context.getBeanDefinition("interService").attributeNames();
            }
        }

Ver el atributo de beanDefinition correspondiente a interService.

imagen.png

imagen.png

imagen.png

Sabemos que BeanDefinition se usa para describir su clase empresarial, entonces, ¿quién describirá BeanDefinino?

¡Se describe estableciendo valores de atributos!

Por ejemplo, el modo proxy de beanDefinition, etc., se mencionará más adelante. ¡El FULL y LITE aquí son los signos de si generar un agente!

具体区别可参考: blog.csdn.net/tales522/ar…

1.2 BeanMetadataElement:作用是获取bd对应的class的磁盘文件位置

    public interface BeanMetadataElement {
        //获取源对象,可能返回null
        Object getSource();
     }

BeanDefinition中存了业务类在虚拟机中的class,这个上篇博文讲了。

但是这个class文件存在你电脑硬盘哪里呢?

getSource翻译成中文就是获取源,对象的源是class,那class的源就是你硬盘上的文件。看下面代码:

    public class SpringTest {
        public static void main(String[] args) throws InterruptedException {
            AnnotationConfigApplicationContext context = new    
                                                AnnotationConfigApplicationContext();
            //注册配置类
            context.register(Config.class);
            //加载或者刷新当前的配置信息
            context.refresh();
            //获取InterService.class的源
            System.out.println(context.getBeanDefinition("interService").getSource());
        }
    }

//输出:file [E:\study\spring-framework\source-code\out\production\classes\tyrant\InterService.class] 

1.2.1 实现:BeanMetadataAttributeAccessor

BeanMetadataElement接口提供了获取源的抽象方法。

真正的实现是在它的实现类BeanMetadataAttributeAccessor中。

BeanMetadataAttributeAccessor继承了AttributeAccessorSupport并且实现了BeanMetadataElement接口。

AttributeAccessorSupport实现了上面的AttributeAccessor。

我们看一下它的源码:

    public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
    
        @Nullable
        private Object source;
    
        /**
         * Set the configuration source {@code Object} for this metadata element.
         * <p>The exact type of the object will depend on the configuration mechanism used.
         * 设置源
         */
        public void setSource(@Nullable Object source) {
            this.source = source;
        }
    
        @Override
        @Nullable
        //获取源
        public Object getSource() {
            return this.source;
        }
     
        //设置属性值,如果已经存在就覆盖,不存在就添加,BeanMetadataAttribute封装了键值对
        //注意value是1个BeanMetadataAttribute
        public void addMetadataAttribute(BeanMetadataAttribute attribute) {
            //super指的是AttributeAccessorSupport
            //AttributeAccessorSupport中维护了1个LinkedHashMap用于存放BD的属性
            super.setAttribute(attribute.getName(), attribute);
        }
        
        /**
         * 根据名字获取属性键值对的封装对象BeanMetadataAttribute
         */
        @Nullable
        public BeanMetadataAttribute getMetadataAttribute(String name) {
            //super指的是AttributeAccessorSupport
            //AttributeAccessorSupport中维护了1个LinkedHashMap用于存放BD的属性
            return (BeanMetadataAttribute) super.getAttribute(name);
        }
        
        //设置属性值,name表示键,value表示值
        @Override
        public void setAttribute(String name, @Nullable Object value) {
            super.setAttribute(name, new BeanMetadataAttribute(name, value));
        }
        
        @Override
        @Nullable
        //根据键获取属性值
        public Object getAttribute(String name) {
            BeanMetadataAttribute attribute = (BeanMetadataAttribute) 
                                                        super.getAttribute(name);
            return (attribute != null ? attribute.getValue() : null);
        }
        
        @Override
        @Nullable
        //移除属性值,并返回值,不存在就返回空
        public Object removeAttribute(String name) {
            BeanMetadataAttribute attribute 
                = (BeanMetadataAttribute) super.removeAttribute(name);
            return (attribute != null ? attribute.getValue() : null);
        }
    }

BeanMetadataAttributeAccessor不但继承了AttributeAccessorSupport还实现了BeanMetadataElement,换言之,既可以操作属性值,也可以操作源。

1.2.1.1BeanMetadataAttribute

上面代码中的BeanMetadataAttribute其实就是对BeanDefinition的属性的键值对进行了封装,如下:

    public class BeanMetadataAttribute implements BeanMetadataElement {
        /**
         * 属性信息
         */
        private final String name;  // 属性名
        private final Object value; // 属性值
        
        // bd的class对应的文件位置
        private Object source;      
                                    
        /**
         * 构造器(设置属性信息)
         */
        public BeanMetadataAttribute(String name, Object value) {
            Assert.notNull(name, "Name must not be null");
            this.name = name;
            this.value = value;
        }
    
        /**
         * 获取属性名、属性值以及获取、设置属性所属对象
         */
        public String getName() {
            return this.name;
        }
        public Object getValue() {
            return this.value;
        }
        public void setSource(Object source) {
            this.source = source;
        }
        @Override
        public Object getSource() {
            return this.source;
        }
        /**
         * 判断属性是否相等
         */
        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }
            if (!(other instanceof BeanMetadataAttribute)) {
                return false;
            }
            BeanMetadataAttribute otherMa = (BeanMetadataAttribute) other;
            return (this.name.equals(otherMa.name) &&
                    ObjectUtils.nullSafeEquals(this.value, otherMa.value) &&
                    ObjectUtils.nullSafeEquals(this.source, otherMa.source));
        }
        @Override
        public int hashCode() {
            return this.name.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.value);
        }
        @Override
        public String toString() {
            return "metadata attribute '" + this.name + "'";
        }
    }

imagen.png

至此,我们讲完了BeanDefinition接口、父接口、父接口实现类的源代码,BeanDefinition的实现类会继承BeanDefinition父接口的实现类。到此为止,BeanDefinition的实现类可以操作属性和源,下面讲解BeanDefinition的实现类如何实现BeanDefinition接口。

总结

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement   
BeanDefinition接口的父接口:

 1. AttributeAccessor
         1.1 实现类AttributeAccessorSupport是1个抽象类,作用是操作bd的属性,属性存放在LinkedHashMap。
         1.2 LinkedHashMap的keyString,value是BeanMetadataAttribute。
         
 2. BeanMetadataElement
         2.1 实现类BeanMetadataAttributeAccessor,作用是获取源即bd对应的class的磁盘文件位置
         2.2 实现类BeanMetadataAttributeAccessor继承了AttributeAccessorSupport既可以操作属性值,也可以操作源
         2.3 通过重写AttributeAccessorSupport抽象类的方法和BeanMetadataAttribute对象操作bd的属性。
 ***/     

Resumen de una oración: la clase de implementación BeanDefinition BeanMetadataAttributeAccessor implementa BeanMetadataElement y hereda AttributeAccessorSupport. Puede establecer y obtener la fuente, y también puede establecer y obtener el valor de propiedad de bd.

Supongo que te gusta

Origin juejin.im/post/7234909292447744037
Recomendado
Clasificación