栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Framework 源码阅读(二):BeanDefinition的作用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Framework 源码阅读(二):BeanDefinition的作用

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;


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,它的源码也比较短,大家可以自己去看看。

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;



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 Map beanDefinitionMap = 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实例不一样。

	private  void doRegisterBean(Class beanClass, @Nullable String name,
			@Nullable Class[] 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 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 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 Map mergedBeanDefinitions = 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,每个人的理解不同,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/356987.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号