上一篇Spring framework源码阅读博客,博主介绍了Aware接口及其实现类的作用,Aware的设计模式是模板模式,而BeanDefinition的设计模式也是模板模式,它们都基于某种职责定义了一个模板,符合开闭原则,对扩展开放,对修改关闭,扩展在子类中实现。
- Spring framework 源码阅读(一):Aware接口及其实现类的作用
- 设计模式-模板模式(Template Pattern)
- 设计模式的七大原则
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;
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的公共属性。
通用方法的实现:
@Override
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
@Override
@Nullable
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
if (beanClassObject instanceof Class) {
return ((Class>) beanClassObject).getName();
}
else {
return (String) beanClassObject;
}
}
@Override
public void setScope(@Nullable String scope) {
this.scope = scope;
}
@Override
@Nullable
public String getScope() {
return this.scope;
}
@Override
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}
@Override
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(this.scope);
}
@Override
public boolean isAbstract() {
return this.abstractFlag;
}
@Override
public void setLazyInit(boolean lazyInit) {
this.lazyInit = lazyInit;
}
@Override
public boolean isLazyInit() {
return (this.lazyInit != null && this.lazyInit.booleanValue());
}
...
也添加了新的属性和方法,涉及到autowire(自动注入):
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
public static final int AUTOWIRE_ConSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
@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;
...
public void setDependencyCheck(int dependencyCheck) {
this.dependencyCheck = dependencyCheck;
}
public int getDependencyCheck() {
return this.dependencyCheck;
}
涉及到qualifier(限定符):
public void addQualifier(AutowireCandidateQualifier qualifier) {
this.qualifiers.put(qualifier.getTypeName(), qualifier);
}
public boolean hasQualifier(String typeName) {
return this.qualifiers.containsKey(typeName);
}
@Nullable
public AutowireCandidateQualifier getQualifier(String typeName) {
return this.qualifiers.get(typeName);
}
public Set getQualifiers() {
return new linkedHashSet<>(this.qualifiers.values());
}
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,它的源码也比较短,大家可以自己去看看。
RootBeanDefinitionRootBeanDefinition表示在运行时支持Spring BeanFactory中特定bean的合并BeanDefinition。它可能是从相互继承的多个原始BeanDefinition创建的(通常注册为GenericBeanDefinition)。RootBeanDefinition本质上是运行时的统一BeanDefinition视图。
RootBeanDefinition也可用于在配置阶段注册单个BeanDefinition。然而,自Spring2.5以来,以编程方式注册BeanDefinition的首选方法是GenericBeanDefinition类。GenericBeanDefinition的优点是它允许动态定义父依赖项,而不是将角色硬编码(hard-coding)为RootBeanDefinition。
GenericBeanDefinitionGenericBeanDefinition是标准BeanDefinition的一站式服务。与任何BeanDefinition一样,它允许指定类以及可选的构造函数参数值和属性值。可以灵活地配置parentName属性,以便从父BeanDefinition中进行派生。通常,使用GenericBeanDefinition类注册用户可见的BeanDefinition。在父子关系恰好是预先确定的情况下,使用RootBeanDefinition和ChildBeanDefinition。
代码也很短:
先在Spring framework源码中增加一个application module,这在之前的博文中已经介绍过了,这里就不再赘述:
- 编译 Spring framework 5.2.17源码 & 在源码中使用 ApplicationContext 获取定义的Bean
IMessageService接口:
package com.kaven.service;
public interface IMessageService {
String getMessage();
}
MessageServiceImpl实现类:
package com.kaven.service.impl;
import com.kaven.service.IMessageService;
import org.springframework.stereotype.Service;
@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;
@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 {
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";
public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalCommonAnnotationProcessor";
public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalPersistenceAnnotationProcessor";
public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
"org.springframework.context.event.internalEventListenerProcessor";
public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
"org.springframework.context.event.internalEventListenerFactory";
public static Set 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 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实例的信息。
private final MapbeanDefinitionMap = new ConcurrentHashMap<>(256); private volatile List 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 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实例不一样。
privatevoid doRegisterBean(Class beanClass, @Nullable String name, @Nullable Class extends Annotation>[] qualifiers, @Nullable Supplier 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的操作,在bean需要实例化之前会被执行,如AbstractBeanFactory抽象类的doGetBean方法(删除了不相关的代码):
protectedT doGetBean( String name, @Nullable Class 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的键值对。
private final MapmergedBeanDefinitions = new ConcurrentHashMap<>(256);
RootBeanDefinition类中的stale属性,使用volatile修饰符修饰,保证了可见性。
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,每个人的理解不同,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。



