Spring Framework 源码阅读(二):BeanDefinition的作用
上一篇Spring Framework源码阅读博客,博主介绍了Aware接口及其实现类的作用,Aware的设计模式是模板模式,而BeanDefinition的设计模式也是模板模式,它们都基于某种职责定义了一个模板,符合开闭原则,对扩展开放,对修改关闭,扩展在子类中实现。
- Spring Framework 源码阅读(一):Aware接口及其实现类的作用
- 设计模式-模板模式(Template Pattern)
- 设计模式的七大原则
BeanDefinition接口的定义
package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/**
* A BeanDefinition describes a bean instance, which has property values,
* constructor argument values, and further information supplied by
* concrete implementations.
* * <p>This is just a minimal interface: The main intention is to allow a
* {@link BeanFactoryPostProcessor} to introspect and modify property values
* and other bean metadata.
* * @author Juergen Hoeller
* @author Rob Harrop
* @since 19.03.2004
* @see ConfigurableListableBeanFactory#getBeanDefinition
* @see org.springframework.beans.factory.support.RootBeanDefinition
* @see org.springframework.beans.factory.support.ChildBeanDefinition
*/
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
...
}
-
BeanDefinition描述bean实例,比如bean实例具有的属性值、构造函数参数值以及由具体实现提供的进一步信息。 - 主要目的是允许
BeanFactoryPostProcessor检查和修改属性值以及其他bean元数据,BeanFactoryPostProcessor博主以后会进行介绍,不然会涉及到很多其他知识,显得杂乱无章,要尽量遵守单一职责原则。
为什么需要BeanDefinition?这就要讨论Java对象和bean有什么不同,很显然bean也是Java对象,但它拥有Java对象所没有的功能,它可以在Spring容器中很容易实现自动注入、懒加载、多种作用域和根据各种限定条件进行初始化等,Java中的类可以描述该类实例的属性和行为,因此bean也需要有描述它附加功能的定义,不然它只是一个Java对象而已,这就是BeanDefinition的作用,从接口的命名也可看出来。
BeanDefinition接口的方法和属性:

属性
-
SCOPE_SINGLETON:bean的单例作用域,把bean设置为单例作用域时,Spring容器只会创建该bean的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例。 -
SCOPE_PROTOTYPE:bean的原型作用域,把bean设置为原型作用域时,每次对bean的请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时Spring容器都会创建一个新的bean实例。bean的其他作用域(request、session、globalSession)需要在Web环境中才能使用,以后博主再进行详细介绍。 -
ROLE_APPLICATION:bean的角色指示,指示该BeanDefinition是应用程序的主要部分。通常对应于用户定义的bean。 -
ROLE_SUPPORT:bean的角色指示,指示该BeanDefinition是某些配置(通常是外部的ComponentDefinition)的支撑部分。 -
ROLE_INFRASTRUCTURE:bean的角色指示,指示该BeanDefinition完全提供后台角色,与终端用户无关。
方法
-
setParentName、getParentName:设置和获取父BeanDefinition名称的方法,为了描述bean之间的继承关系,BeanDefinition也有父子关系,之后会介绍到合并BeanDefinition的概念。 -
setBeanClassName、getBeanClassName:设置和获取bean的类名。 -
setScope、getScope:设置和获取bean的作用域。 -
setLazyInit、isLazyInit:设置bean为懒加载、判断bean是否为懒加载。 -
setDependsOn、getDependsOn:设置和获取bean所依赖的bean的名称数组(保证首先初始化这些bean)。 -
setAutowireCandidate、isAutowireCandidate:AutowireCandidate表示bean是否是自动注入到其他bean的候选。仅影响基于类型(byType)的自动注入。它不会影响按名称(byName)的显式引用,即使指定的bean未标记为autowire候选,也会解析为显式引用。因此,如果名称匹配,会按名称自动注入bean。 -
setPrimary、isPrimary:设置和判断bean是否是自动注入到其他bean的首选。 -
setFactoryBeanName、getFactoryBeanName:FactoryBean和BeanFactory是不一样的概念,FactoryBean也是bean,不过它可以用于创建某一类型的bean(所有是一个factory,也是一个bean),因此借助FactoryBean可以定制化创建bean的过程。这两个方法就是设置和获取bean的FactoryBeanName(可以为null)。 -
setFactoryMethodName、getFactoryMethodName:FactoryBean通过FactoryMethod来创建某一类型的bean。这两个方法就是设置和获取bean的FactoryMethod(可以为null)。 -
getConstructorArgumentValues、hasConstructorArgumentValues:获取bean的构造器参数值、判断bean是否有构造器参数值。 -
getPropertyValues、hasPropertyValues:获取要应用于bean的新实例的属性值、判断是否有要应用于bean的新实例的属性值。 -
setInitMethodName、getInitMethodName:设置和获取bean初始化方法的名称。 -
setDestroyMethodName、getDestroyMethodName:设置和获取bean销毁方法的名称。 -
setRole、getRole:设置和获取bean的角色。 -
setDescription、getDescription:设置和获取BeanDefinition的human-readable description(便于人类阅读的描述)。 -
getResolvableType:基于BeanDefinition或其他特定元数据,返回该BeanDefinition的可解析类型。这通常在运行时合并的BeanDefinition(下面会进行介绍)上完全解析,但不一定在配置时定义的实例上完全解析。 -
isSingleton、isPrototype:判断bean是否是单例、原型bean。 -
isAbstract:判断bean是否是abstract,如果是abstract就不需要实例化了。 -
getResourceDescription:获取BeanDefinition来自的Resource的描述(用于在出现错误时显示上下文)。 -
getOriginatingBeanDefinition:返回原始的BeanDefinition,如果没有,则返回null。
BeanDefinition接口还继承了AttributeAccessor接口和BeanMetadataElement接口。

-
AttributeAccessor接口:定义了通用的接口,用于向任意对象附加元数据或从任意对象访问元数据。 -
BeanMetadataElement接口:由携带配置源对象的bean元数据元素实现的接口。
使用这些定义来描述bean实例,而具体实现下放到子类中,比如AbstractBeanDefinition、ChildBeanDefinition、RootBeanDefinition以及GenericBeanDefinition,接下来博主会详细介绍它们的作用。
AbstractBeanDefinition
之前介绍过BeanDefinition的设计模式是模板模式,AbstractBeanDefinition抽象类实现了BeanDefinition接口中的通用方法。
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
...
}AbstractBeanDefinition是具体、完备的BeanDefinition基类,并且分解出了GenericBeanDefinition、RootBeanDefinition和ChildBeanDefinition的公共属性。

通用方法的实现:
/**
* 指定bean定义的bean类名
*/
@Override
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
/**
* 返回bean定义的bean类名
*/
@Override
@Nullable
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
if (beanClassObject instanceof Class) {
return ((Class<?>) beanClassObject).getName();
}
else {
return (String) beanClassObject;
}
}
/**
* 设置bean的作用域
*/
@Override
public void setScope(@Nullable String scope) {
this.scope = scope;
}
/**
* 返回bean的作用域名称
*/
@Override
@Nullable
public String getScope() {
return this.scope;
}
/**
* 是否是单例bean
*/
@Override
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}
/**
*是否是原型bean
*/
@Override
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(this.scope);
}
/**
* 是否是abstract,如果是就不会进行实例化
*/
@Override
public boolean isAbstract() {
return this.abstractFlag;
}
/**
* 设置bean的加载方式为懒加载
*/
@Override
public void setLazyInit(boolean lazyInit) {
this.lazyInit = lazyInit;
}
/**
* 判断bean是否设置懒加载
*/
@Override
public boolean isLazyInit() {
return (this.lazyInit != null && this.lazyInit.booleanValue());
}
...
也添加了新的属性和方法,涉及到autowire(装配bean的属性):
/**
* 表示没有自动装配的常量
*/
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
/**
* 表示按名称自动装配bean属性的常量
*/
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
/**
* 表示按类型自动装配bean属性的常量
*/
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
/**
* 表示通过构造函数自动装配bean属性的常量
*/
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
/**
* 表示通过bean类的内部检测来确定适当的自动装配策略的常量
*/
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
/**
* 设置自动装配模式
*/
public void setAutowireMode(int autowireMode) {
this.autowireMode = autowireMode;
}
/**
* 返回自动装配模式
*/
public int getAutowireMode() {
return this.autowireMode;
}
/**
* 返回已解析的自动装配模式编码
*/
public int getResolvedAutowireMode() {
if (this.autowireMode == AUTOWIRE_AUTODETECT) {
// 确定是应用setter自动装配还是构造函数自动装配
// 如果它有一个无参数构造函数,则被视为setter自动装配
// 否则将尝试构造函数自动装配
Constructor<?>[] constructors = getBeanClass().getConstructors();
for (Constructor<?> constructor : constructors) {
if (constructor.getParameterCount() == 0) {
return AUTOWIRE_BY_TYPE;
}
}
return AUTOWIRE_CONSTRUCTOR;
}
else {
return this.autowireMode;
}
}
...
涉及到dependency check(依赖项检查):
/**
* 表示没有依赖项检查的常量
*/
public static final int DEPENDENCY_CHECK_NONE = 0;
/**
* 表示对象引用的依赖项检查的常量
*/
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
/**
* 表示“简单”属性的依赖项检查的常量
*/
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
/**
* 表示所有属性的依赖项检查的常量
*/
public static final int DEPENDENCY_CHECK_ALL = 3;
...
/**
* 设置依赖项检查的编码,就是上面的0、1、2以及3
*/
public void setDependencyCheck(int dependencyCheck) {
this.dependencyCheck = dependencyCheck;
}
/**
* 返回当前依赖项检查的编码
*/
public int getDependencyCheck() {
return this.dependencyCheck;
}
涉及到qualifier(限定符):
/**
* 注册一个用于autowire候选解析的限定符。
*/
public void addQualifier(AutowireCandidateQualifier qualifier) {
this.qualifiers.put(qualifier.getTypeName(), qualifier);
}
/**
* 返回bean是否具有指定的限定符
*/
public boolean hasQualifier(String typeName) {
return this.qualifiers.containsKey(typeName);
}
/**
* 返回映射到提供的类型名称的限定符
*/
@Nullable
public AutowireCandidateQualifier getQualifier(String typeName) {
return this.qualifiers.get(typeName);
}
/**
* 返回所有的限定符。
*/
public Set<AutowireCandidateQualifier> getQualifiers() {
return new LinkedHashSet<>(this.qualifiers.values());
}
/**
* 将限定符从提供的AbstractBeanDefinition复制到此AbstractBeanDefinition
*/
public void copyQualifiersFrom(AbstractBeanDefinition source) {
Assert.notNull(source, "Source must not be null");
this.qualifiers.putAll(source.qualifiers);
}
这些都是AbstractBeanDefinition中新增加的内容(基于特定业务的抽象),当然这些还不是AbstractBeanDefinition的全貌,大家可以自己去探索一下。接下来会介绍AbstractBeanDefinition三个比较重要的子类ChildBeanDefinition、RootBeanDefinition以及GenericBeanDefinition。
ChildBeanDefinition
子Bean(继承了父Bean)的BeanDefinition。子BeanDefinition对父BeanDefinition有固定的依赖关系。
子BeanDefinition将从父BeanDefinition继承构造函数参数值、属性值和方法重写,并具有添加新值的选项。如果指定了init method、destroy method或static factory method,它们将覆盖相应父BeanDefinition的设置。其余设置将始终取自子BeanDefinition:depends on、autowire mode、dependency check、singleton以及lazy init。
自Spring2.5以来,以编程方式注册BeanDefinition的首选方法是GenericBeanDefinition类,它允许通过setParentName方法动态定义父依赖项。对于大多数用例,这有效地取代了ChildBeanDefinition类。因此这里不会详细地介绍ChildBeanDefinition,它的源码也比较短,大家可以自己去看看。
RootBeanDefinition
RootBeanDefinition表示在运行时支持Spring BeanFactory中特定bean的合并BeanDefinition。它可能是从相互继承的多个原始BeanDefinition创建的(通常注册为GenericBeanDefinition)。RootBeanDefinition本质上是运行时的统一BeanDefinition视图。
RootBeanDefinition也可用于在配置阶段注册单个BeanDefinition。然而,自Spring2.5以来,以编程方式注册BeanDefinition的首选方法是GenericBeanDefinition类。GenericBeanDefinition的优点是它允许动态定义父依赖项,而不是将角色硬编码(hard-coding)为RootBeanDefinition。
GenericBeanDefinition
GenericBeanDefinition是标准BeanDefinition的一站式服务。与任何BeanDefinition一样,它允许指定类以及可选的构造函数参数值和属性值。可以灵活地配置parentName属性,以便从父BeanDefinition中进行派生。通常,使用GenericBeanDefinition类注册用户可见的BeanDefinition。在父子关系恰好是预先确定的情况下,使用RootBeanDefinition和ChildBeanDefinition。
代码也很短:

创建module
先在Spring Framework源码中增加一个application module,这在之前的博文中已经介绍过了,这里就不再赘述:
- 编译 Spring Framework 5.2.17源码 & 在源码中使用 ApplicationContext 获取定义的Bean

IMessageService接口:
package com.kaven.service;
/**
* @Author: ITKaven
* @Date: 2021/09/25 14:04
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
public interface IMessageService {
String getMessage();
}
MessageServiceImpl实现类:
package com.kaven.service.impl;
import com.kaven.service.IMessageService;
import org.springframework.stereotype.Service;
/**
* @Author: ITKaven
* @Date: 2021/09/25 14:05
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
@Service("message")
public class MessageServiceImpl implements IMessageService {
@Override
public String getMessage() {
return "Hello Kaven";
}
}
Application启动类:
package com.kaven;
import com.kaven.service.IMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* @Author: ITKaven
* @Date: 2021/09/25 13:54
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
@ComponentScan({"com.kaven"})
public class Application {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
IMessageService messageServiceBean = (IMessageService) applicationContext.getBean("message");
System.out.println(messageServiceBean.getMessage());
Test test = (Test) applicationContext.getBean("test");
System.out.println("message bean: " + (test.messageService == messageServiceBean));
Test test2 = (Test) applicationContext.getBean("test");
System.out.println("message bean: " + (test2.messageService == messageServiceBean));
System.out.println("test bean: " + (test == test2));
System.out.println(applicationContext.getBeanDefinitionCount());
Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach(System.out::println);
}
@Component("test")
@Scope("prototype")
static class Test {
@Autowired
private IMessageService messageService;
}
}
运行输出:
> Task :application:Application.main()
Hello Kaven
message bean: true
message bean: true
test bean: false
7
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
application
test
message
BUILD SUCCESSFUL in 19s
61 actionable tasks: 2 executed, 59 up-to-date
源码分析 - 注册BeanDefinition
上下文中有7个BeanDefinition,而test bean被获取了两次,为什么没有两个test BeanDefinition?因为每个BeanDefinition描述了一类bean,并且BeanDefinition是根据beanName获取的,BeanDefinition类似于类(对象定义),而bean类似于对象,所以beanName就类似于className,类描述了该类所有对象的行为和属性,BeanDefinition也是如此。从输出结果上来看,bean默认是单例(除非使用@Scope注解改变其作用域),其实在AbstractBeanDefinition的源码中也可以发现作用域的默认值。
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
/**
* 默认作用域名称的常量:"",等同于单例状态(会被替换为单例,在相关源码的注释中有解释)
*/
public static final String SCOPE_DEFAULT = "";
@Nullable
private String scope = SCOPE_DEFAULT;
...
}AbstractBeanDefinition的源码中还有一些比较常见配置的默认值,比如bean默认不是abstract的(因此需要被实例化)、lazyInit为null(因此不会被懒加载)、没有自动装配、依赖项检查为DEPENDENCY_CHECK_NONE(没有依赖项检查)、是自动注入的候选bean和不是首选bean(primary):
private boolean abstractFlag = false;
@Nullable
private Boolean lazyInit;
private int autowireMode = AUTOWIRE_NO;
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
private boolean autowireCandidate = true;
private boolean primary = false;
很显然下面这4个BeanDefinition是Spring定义的:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
它们在AnnotationConfigUtils抽象类的registerAnnotationConfigProcessors方法中出现:
public abstract class AnnotationConfigUtils {
/**
* 内部管理Configuration注解的处理器的bean名称
*/
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
/**
* 内部管理Autowired注解的处理器的bean名称
*/
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
/**
* 内部管理JSR-250注解的处理器的bean名称
*/
public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalCommonAnnotationProcessor";
/**
* 内部管理JPA注解的处理器的bean名称
*/
public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
/**
* 内部管理EventListener注解的处理器的bean名称
*/
public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
"org.springframework.context.event.internalEventListenerProcessor";
/**
* 内部管理EventListenerFactory的bean名称
*/
public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
"org.springframework.context.event.internalEventListenerFactory";
/**
* 在给定registry中注册所有相关的注解post processors
* @param registry 要在其上操作的registry
* @param source 触发此注册的配置源元素(已提取),可能为null
* @return Set<BeanDefinitionHolder>,其中包含此调用实际注册的所有BeanDefinition
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
...
}其实这个BeanDefinitionRegistry registry参数就是博主在Application类中创建的AnnotationConfigApplicationContext实例。并且这里定义的BeanDefinition是RootBeanDefinition 实例(RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);,博主在后面会进行讨论)。


AnnotationConfigApplicationContext类的父类GenericApplicationContext实现了BeanDefinitionRegistry 接口。

下一步调用了AnnotationConfigUtils抽象类的的registerPostProcessor方法(可以看见role设置为ROLE_INFRASTRUCTURE):
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
之后又调用了GenericApplicationContext类的registerBeanDefinition方法,很显然是AnnotationConfigApplicationContext类继承了父类GenericApplicationContext的registerBeanDefinition方法。
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
GenericApplicationContext类的beanFactory属性是DefaultListableBeanFactory类的实例。
private final DefaultListableBeanFactory beanFactory;
DefaultListableBeanFactory类是Spring默认实现的ConfigurableListableBeanFactory和BeanDefinitionRegistry接口:一个基于bean definition元数据的成熟bean factory。
先不纠结这些类的作用,类太多了,无法把所有类的作用和原理都理解的一清二楚,需要关注的是DefaultListableBeanFactory类中的beanDefinitionMap和beanDefinitionNames属性,很显然它们存储了beanName以及相关BeanDefinition实例的信息。
/** BeanDefinition对象的映射,bean名称为key */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** 按注册顺序列出BeanDefinition名称 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
下一步调用了DefaultListableBeanFactory类中的registerBeanDefinition方法,在该方法中,将beanName和beanDefinition信息存储到了beanDefinitionMap和beanDefinitionNames属性中:
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
这4个内置bean的BeanDefinition就完成了注册。
为什么会注册这些内置bean?可以看一下调用链:

先是在main方法中调用了AnnotationConfigApplicationContext类的构造函数:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}又接着调用了AnnotationConfigApplicationContext类的无参构造函数:
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}然后连续调用了AnnotatedBeanDefinitionReader类的两个构造函数:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}从这里就开始注册内置bean的BeanDefinition了。
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
接着会注册application bean的BeanDefinition,调用链如下图所示:


@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
在调用链的doRegisterBean方法中可以发现application bean的BeanDefinition是AnnotatedGenericBeanDefinition(GenericBeanDefinition的子类)实例,明显和内置bean的RootBeanDefinition实例不一样。
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
可以回顾一下博主对RootBeanDefinition的介绍:
RootBeanDefinition表示在运行时支持Spring BeanFactory中特定bean的合并BeanDefinition。RootBeanDefinition本质上是运行时的统一BeanDefinition视图。
RootBeanDefinition也可用于在配置阶段注册单个BeanDefinition。然而,自Spring2.5以来,以编程方式注册BeanDefinition的首选方法是GenericBeanDefinition类。
博主的理解:因为内置bean没有父bean,继承关系是明确的,因此内置bean的BeanDefinition也不会有父BeanDefinition,也就不需要进行合并BeanDefinition的操作,此时的BeanDefinition就是内置bean的统一BeanDefinition视图,所以可以直接是RootBeanDefinition实例。
而application bean是用户自定义的bean,继承关系并不明确,是有可能存在继承关系的,因此有可能需要进行合并BeanDefinition的操作,此时的BeanDefinition就不一定是application bean的统一BeanDefinition视图,因此定义为AnnotatedGenericBeanDefinition实例,以便之后可以进行合并BeanDefinition的操作(通过设置parentName)。而什么时候会进行合并BeanDefinition的操作,下面会进行介绍。
test以及message bean的BeanDefinition都是在如下图所示的调用链中被定义:


现在所有bean的BeanDefinition都被注册了,下面介绍合并BeanDefinition。
源码分析 - 合并BeanDefinition
合并BeanDefinition的操作,在bean需要实例化之前会被执行,如AbstractBeanFactory抽象类的doGetBean方法(删除了不相关的代码):
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
}
接着调用了AbstractBeanFactory抽象类的getMergedLocalBeanDefinition方法:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null && !mbd.stale) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}AbstractBeanFactory抽象类的mergedBeanDefinitions属性是一个ConcurrentHashMap实例,存储了以bean名称为key,合并的RootBeanDefinition为value的键值对。
/** 从bean名称映射到合并的RootBeanDefinition */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
RootBeanDefinition类中的stale属性,使用volatile修饰符修饰,保证了可见性。
/** 确定是否需要重新合并BeanDefinition */
volatile boolean stale;
如果之前没有合并过,或者需要重新合并,就会调用AbstractBeanFactory抽象类的getMergedBeanDefinition方法,而先会调用DefaultListableBeanFactory类的getBeanDefinition方法获取beanName对应的BeanDefinition:
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (logger.isTraceEnabled()) {
logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}通过源码,其实可以发现该this(DefaultListableBeanFactory实例)就是之前说的在main方法中创建的AnnotationConfigApplicationContext实例的beanFactory属性。


在调用AbstractApplicationContext类的refresh方法时,将AnnotationConfigApplicationContext实例的beanFactory属性传进去了(删除了部分代码):
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
}
}

因此调用DefaultListableBeanFactory类的getBeanDefinition方法就是获取之前定义的BeanDefinition(通过beanName,内置bean对应RootBeanDefinition实例,而自定义bean对应GenericBeanDefinition实例)。
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
获取beanName对应的BeanDefinition后,返回到AbstractBeanFactory抽象类的getMergedBeanDefinition方法(方法命名相同,和之前不是一样的方法):
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
return getMergedBeanDefinition(beanName, bd, null);
}
又继续调用AbstractBeanFactory抽象类的getMergedBeanDefinition方法(方法命名相同,和之前不是一样的方法):
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 合并BeanDefinition时需要上锁,避免发生线程安全问题
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 没有合并过或者需要重新合并BeanDefinition
if (mbd == null || mbd.stale) {
previous = mbd;
// 没有父BeanDefinition,不需要合并,将原有的BeanDefinition拷贝即可
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
// 非RootBeanDefinition实例,可能是GenericBeanDefinition类或其子类的实例
else {
mbd = new RootBeanDefinition(bd);
}
}
// 有父BeanDefinition,需要合并
else {
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 合并父BeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 合并父BeanDefinition
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// 将合并的父BeanDefinition转换成RootBeanDefinition实例
mbd = new RootBeanDefinition(pbd);
// 子BeanDefinition重写合并的父BeanDefinition得到合并的子BeanDefinition
mbd.overrideFrom(bd);
}
// 作用域为""时(默认),会被替代为SCOPE_SINGLETON(单例),和上面说的对应起来了
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(SCOPE_SINGLETON);
}
// 非单例bean中包含的bean本身不能是单例bean
// 更正这个问题,因为这可能是外部bean的父子合并,在这种情况下,原始内部BeanDefinition将不会继承合并的外部bean的单例状态。
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// 暂时缓存合并的BeanDefinition
// 以后可能会重新合并,以获取元数据更改
if (containingBd == null && isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
可见合并的BeanDefinition默认就是RootBeanDefinition实例,这也就是为什么说RootBeanDefinition本质上是运行时的统一BeanDefinition视图的原因了。该方法通过递归调用的形式合并BeanDefinition,这也符合bean之间的继承关系图。
合并BeanDefinition之后,就能知道bean的所有配置信息,就可以进行bean的实例化了。
阅读源码需要耐心,一步步进行Debug,每个人的理解不同,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。










