# 一,什么是BeanDefinition
我一直认为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方法获取对应配置源。