spring源码系列学习一 ------ Bean定义之BeanDefinition定义

81 阅读2分钟

image.png # 一,什么是BeanDefinition

image.png

image.png 我一直认为spring源码的阅读是从熟练使用spring的框架开始的,从xml的配置中我们可以看到很多srping中bean的属性,如是单例还是原型模式,自动注入的类型,也有多个同类型接口的primary,是否由工厂类生成亦或是依赖于哪个类先建立的情况,也有是否延迟加载和父类指向以及类对象等等的属性。 BeanDefinition的中文翻译是Bean定义,由上图看出,BeanDefinition自身的方法与我们XML中定义的中所拥有的属性是相同的,而BeanDefinition又继承了属性访问AttributeAccessor和Bean元数据BeanMetadataElement两个接口,那什么时候我们可以让spring管理对象呢,如@Bean,@Component以及Component注解的@Service,@Controller以及通过xml配置的bean对象等等。

属性访问接口AttributeAccessor


package org.springframework.core;
import java.util.function.Function;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

/**
 * Interface defining a generic contract for attaching and accessing metadata
 * to/from arbitrary objects.
 *
 * @author Rob Harrop
 * @author Sam Brannen
 * @since 2.0
 */
public interface AttributeAccessor {

   void setAttribute(String name, @Nullable Object value);
    
   @Nullable
   Object getAttribute(String name);

   @SuppressWarnings("unchecked")
   default <T> T computeAttribute(String name, Function<String, T> computeFunction) {
      Assert.notNull(name, "Name must not be null");
      Assert.notNull(computeFunction, "Compute function must not be null");
      Object value = getAttribute(name);
      if (value == null) {
         value = computeFunction.apply(name);
         Assert.state(value != null,
               () -> String.format("Compute function must not return null for attribute named '%s'", name));
         setAttribute(name, value);
      }
      return (T) value;
   }

   @Nullable
   Object removeAttribute(String name);

   boolean hasAttribute(String name);

   String[] attributeNames();

}

我们从它的方法中可以看出,属性访问接口AttributeAccessor共计提供了6个方法,分别为设置属性setAttribute方法,获取属性值getAttribute,属性计算computeAttribute方法,删除属性removeAttribute方法,是否含有某个属性hasAttribute,返回名称数组attributeNames。根据传参和判断来讲,我们基本可以确认,当前接口是通过Map的数据存储和获取来实现,所以我们假定实现当前接口的类本身会含有一个属性Map<String,Object>,至于具体时间先是hash还是其他类型我们先不深究,其中要关注下computeAttribute这个方法,该方法用于传一个参数名和函数接口,当通过当前参数获取值为空的时候,通过函数传人来计算设置新的值。

BeanMetadataElement元数据接口

/*
 * Copyright 2002-2019 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans;

import org.springframework.lang.Nullable;

/**
 * Interface to be implemented by bean metadata elements
 * that carry a configuration source object.
 *
 * @author Juergen Hoeller
 * @since 2.0
 */
public interface BeanMetadataElement {

   /**
    * Return the configuration source {@code Object} for this metadata element
    * (may be {@code null}).
    */
   @Nullable
   default Object getSource() {
      return null;
   }

}

通过元数据接口,我们只看到一个初始化方法getSource,证明后续实现该接口的类肯定会有一个一个属性source,即元数据的配置源,重写get方法获取对应配置源。