一、基础代码
Spring
加载bean实例的代码
public static void main(String[] args) throws IOException {
// 1.获取资源
Resource resource = new ClassPathResource("bean.xml");
// 2.获取BeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 3.获取资源的解析器
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// 4.装载资源
reader.loadBeanDefinitions(resource);
// 5.获取Bean实例
Book book = factory.getBean(Book.class);
System.out.println(book);
}
这段代码是 Spring 中编程式使用 IoC 容器,通过这四段简单的代码,我们可以初步判断 IoC 容器的使用过程。整个过程就分为三个步骤:
资源定位。我们一般用外部资源来描述 Bean 对象,所以在初始化 IoC 容器的第一步就是需要定位这个外部资源。
装载。装载就是 BeanDefinition
的载入。BeanDefinitionReader
读取、解析 Resource 资源,也就是将用户定义的 Bean 表示成 IoC 容器的内部数据结构:BeanDefinition
。
注册。向 IoC 容器注册在第二步解析好的 BeanDefinition
,这个过程是通过BeanDefinitionRegistry
接口来实现的。在 IoC 容器内部其实是将第二个过程解析得到的BeanDefinition
注入到一个HashMap
容器中,IoC 容器就是通过这个HashMap
来维护这些BeanDefinition
的。
1)在这里需要注意的一点是这个过程并没有完成依赖注入(Bean 创建),Bean 创建是发生在应用第一次调用getBean()
方法,向容器索要 Bean 时。
2)当然我们可以通过设置预处理,即对某个 Bean 设置lazyinit = false
属性,那么这个 Bean 的依赖注入就会在容器初始化的时候完成。
简单点说,上面步骤的结果是:XML Resource -> XML Document -> Bean Definition
二、BeanDefinition
上面讲完了介绍到我们解析的Bean
标签会封装成BeanDefinition
,那么接下来看一下
1.基础介绍
org.springframework.beans.factory.config.BeanDefinition
,是一个接口,它描述了一个 Bean 实例的定义,包括属性值、构造方法值和继承自它的类的更多信息。代码如下:
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 其中方法就不粘贴了,太多了
}
2.BeanDefinition 的父关系
BeanDefinition
继承 AttributeAccessor
和 BeanMetadataElement
接口。两个接口定义如下:
org.springframework.cor.AttributeAccessor
接口,定义了与其它对象的(元数据)进行连接和访问的约定,即对属性的修改,包括获取、设置、删除。代码如下:
public interface AttributeAccessor {
void setAttribute(String name, @Nullable Object value);
@Nullable
Object getAttribute(String name);
@Nullable
Object removeAttribute(String name);
boolean hasAttribute(String name);
String[] attributeNames();
}
org.springframework.beans.BeanMetadataElement
接口,Bean 元对象持有的配置元素可以通过 getSource()
方法来获取。代码如下:
public interface BeanMetadataElement {
@Nullable
default Object getSource() {
return null;
}
}
3.BeanDefinition 的子关系
我们常用的三个实现类有:
org.springframework.beans.factory.support.ChildBeanDefinition
org.springframework.beans.factory.support.RootBeanDefinition
org.springframework.beans.factory.support.GenericBeanDefinition
ChildBeanDefinition
、RootBeanDefinition
、GenericBeanDefinition
三者都继承AbstractBeanDefinition
抽象类,即AbstractBeanDefinition
对三个子类的共同的类信息进行抽象。- 如果配置文件中定义了父 和 子 ,则父 用
RootBeanDefinition
表示,子 用ChildBeanDefinition
表示,而没有父 的就使用RootBeanDefinition
表示。 GenericBeanDefinition
为一站式服务类。
三、调用链
1.loadBeanDefinitions() 加载
加载BeanDefinition
// XmlBeanDefinitionReader XML解析类
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 将Resource资源封装成EncodedResource,封装的原因是为了进行编码,保证内容读取的正确性
return loadBeanDefinitions(new EncodedResource(resource));
}
// XmlBeanDefinitionReader XML解析类
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
// 获取已经加载过的资源
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
// 将当前资源加入记录中,如果已存在,则抛出异常
// 主要为了避免一个EncodedResource在加载时,还没加载完成,又加载自身,从而导致死循环
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
// 获取输入流
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
// 设置编码
inputSource.setEncoding(encodedResource.getEncoding());
}
// **核心逻辑部分,执行加载 BeanDefinition
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
// 缓存中剔除该资源,代表加载完了该文件
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
-> doLoadBeanDefinitions()
// XmlBeanDefinitionReader XML解析类
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
// 获取XML Document实例
Document doc = doLoadDocument(inputSource, resource);
// 根据 Document 实例,注册 Bean 信息
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
2.doLoadDocument()
将XML
文件解析成Docuemnt
private DocumentLoader documentLoader = new DefaultDocumentLoader();
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
// DefaultDocumentLoader 默认的文档加载器
@Override
public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
if (logger.isTraceEnabled()) {
logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]");
}
DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
return builder.parse(inputSource);
}
3.registerBeanDefinitions() 开始注册
注册BeanDefinition
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// <1>创建对象BeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// <2>获取已注册的BeanDefinition数量
int countBefore = getRegistry().getBeanDefinitionCount();
// <3>创建XmlReaderContext
// <4>注册新的Bean
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// <5>两个相减,返回注册成功的数量
return getRegistry().getBeanDefinitionCount() - countBefore;
}
-> registerBeanDefinitions()
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
doRegisterBeanDefinitions(doc.getDocumentElement());
}
-> doRegisterBeanDefinitions()
该方法特殊处理profile
属性,然后进行解析
protected void doRegisterBeanDefinitions(Element root) {
// 记录老的 BeanDefinitionParserDelegate 对象
BeanDefinitionParserDelegate parent = this.delegate;
// 创建 BeanDefinitionParserDelegate 对象,并进行设置到 delegate
// *** 它负责解析Document的各种对象
this.delegate = createDelegate(getReaderContext(), root, parent);
// 检查 <beans /> 根标签的命名空间是否为空,或者是 http://www.springframework.org/schema/beans
if (this.delegate.isDefaultNamespace(root)) {
// 处理profile属性
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
// 使用分隔符切分,可能有多个 profile 。
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// 如果所有 profile 都无效,则不进行注册
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
// 解析前处理, 空实现
preProcessXml(root);
// 解析
parseBeanDefinitions(root, this.delegate);
// 解析后处理, 空实现
postProcessXml(root);
this.delegate = parent;
}
protected void preProcessXml(Element root) {
}
protected void postProcessXml(Element root) {
}
4.parseBeanDefinitions() 分类解析
下面代码中会区分2类,
- 默认命名空间,例如:
<bean id="book" class="com.h3c.ss.Book"></bean>
- 自定义注解方式,例如:
<tx:annotation-driven>
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// <1>如果根节点使用默认命名空间,执行默认解析
if (delegate.isDefaultNamespace(root)) {
// 遍历子节点,也就是XML文件中的内容
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
// 如果该节点使用默认命名空间,执行默认解析
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
// 否则执行自定义解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
//<2> 根节点非默认命名空间,执行自定义解析
delegate.parseCustomElement(root);
}
}
-> parseDefaultElement() 解析默认命名空间
public static final String BEAN_ELEMENT = "bean";
public static final String IMPORT_ELEMENT = "import";
public static final String ALIAS_ATTRIBUTE = "alias";
public static final String NESTED_BEANS_ELEMENT = "beans";
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析import标签
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// 解析alias
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// 解析bean
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
// 解析嵌套的bean
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
-> parseCustomElement() 自定义解析
5.importBeanDefinitionResource() 解析import标签
6.processBeanDefinition() 解析bean标签
解析工作分为三步:
- 解析默认标签。
- 解析默认标签后下得自定义标签。
- 注册解析后的 BeanDefinition 。
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// <1> 如果解析成功,则返回 BeanDefinitionHolder 对象。而 BeanDefinitionHolder 为 name 和 alias 的 BeanDefinition 对象
// 如果解析失败,则返回 null 。
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// <2> 解析默认标签后下得自定义标签
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// <3> 进行 BeanDefinition 的注册
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
-> 第1步:解析beanName
- 解析
id
、name
属性,确定aliases
集合 - 检测
beanName
是否唯一 - 对属性进行解析并封装成
AbstractBeanDefinition
实例beanDefinition
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
return parseBeanDefinitionElement(ele, null);
}
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 获取Id 和 name
String id = ele.getAttribute(ID_ATTRIBUTE);
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// 解析name
List<String> aliases = new ArrayList<>();
if (StringUtils.hasLength(nameAttr)) {
// name属性可以存在多个,可以以不同的分隔符间隔,这里就是用于拆分的工具类
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
// bean名称优先使用id
String beanName = id;
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
// 没有id,则默认使用别名的第1个
beanName = aliases.remove(0);
if (logger.isTraceEnabled()) {
logger.trace("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
// 检查bean是否存在重名现象
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
// 解析属性,构造 AbstractBeanDefinition 对象
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
// beanName如果不存在,则需要系统生成
if (!StringUtils.hasText(beanName)) {
try {
// containingBean传过来的就是Null
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
// 生成唯一的 beanName
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
// 进一步判断
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
// 返回
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
-> 第2步:解析内部标签
第2步的入口来自第1步
@Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
// 解析 class 属性
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
// 解析 parent 属性
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 创建用于承载属性的 AbstractBeanDefinition 实例
// 创建的类型为: GenericBeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析默认 bean 的各种属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// 提取 description
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// tips:
// 下面的一堆是解析 <bean>......</bean> 内部的子元素,
// 解析出来以后的信息都放到 bd 的属性中
// 解析元数据 <meta />
parseMetaElements(ele, bd);
// 解析 lookup-method 属性 <lookup-method />
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析 replaced-method 属性 <replaced-method />
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析构造函数参数 <constructor-arg />
parseConstructorArgElements(ele, bd);
// 解析 property 子元素 <property />
parsePropertyElements(ele, bd);
// 解析 qualifier 子元素 <qualifier />
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
-> 第3步:解析bean属性
第3步的入口来自第2步
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
}
// 解析scope属性
else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
}
else if (containingBean != null) {
// Take default from containing bean in case of an inner bean definition.
bd.setScope(containingBean.getScope());
}
// 解析abstract属性
if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
}
// 解析lazy-init属性
String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
if (isDefaultValue(lazyInit)) {
lazyInit = this.defaults.getLazyInit();
}
bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
bd.setAutowireMode(getAutowireMode(autowire));
if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
}
String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
if (isDefaultValue(autowireCandidate)) {
String candidatePattern = this.defaults.getAutowireCandidates();
if (candidatePattern != null) {
String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
}
}
else {
bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
}
if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
}
// 解析init-method属性
if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
bd.setInitMethodName(initMethodName);
}
else if (this.defaults.getInitMethod() != null) {
bd.setInitMethodName(this.defaults.getInitMethod());
bd.setEnforceInitMethod(false);
}
// 解析destroy-method属性
if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
bd.setDestroyMethodName(destroyMethodName);
}
else if (this.defaults.getDestroyMethod() != null) {
bd.setDestroyMethodName(this.defaults.getDestroyMethod());
bd.setEnforceDestroyMethod(false);
}
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}
return bd;
}
7.registerBeanDefinition() 注册
从第6步开始,解析完bean标签的各个属性,然后就是要注册到容器中了
// BeanDefinitionReaderUtils#registerBeanDefinition() 该方式是1个工具类,一个中转而已
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 获取beanName
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 存在别名则注册
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
-> registerBeanDefinition() 注册bean
处理过程如下:
- <1> 对
BeanDefinition
进行校验,该校验也是注册过程中的最后一次校验了,主要是对AbstractBeanDefinition
的methodOverrides
属性进行校验。 - <2> 根据
beanName
从缓存中获取BeanDefinition
对象。 - <3> 如果缓存中存在,则根据
allowBeanDefinitionOverriding
标志来判断是否允许覆盖。如果允许则直接覆盖。否则,抛出BeanDefinitionStoreException
异常。 - <4>若缓存中没有指定
beanName
的BeanDefinition
,则判断当前阶段是否已经开始了 Bean 的创建阶段?如果是,则需要对beanDefinitionMap
进行加锁控制并发问题,否则直接设置即可。 - <5> 若缓存中存在该
beanName
或者单例 bean 集合中存在该beanName
,则调用#resetBeanDefinition(String beanName)
方法,重置BeanDefinition
缓存。
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// <1> 校验 BeanDefinition 。
// 校验 beanName 与 beanDefinition 非空
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
// 这是注册前的最后一次校验了,主要是对属性 methodOverrides 进行校验。
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// <2> 从缓存中获取指定 beanName 的 BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// <3> 如果已经存在
// 获取到则代表已经存在
if (existingDefinition != null) {
// 如果配置了不允许覆盖,则抛出异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 覆盖 beanDefinition 大于 被覆盖的 beanDefinition 的 ROLE ,打印 info 日志
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 + "]");
}
}
// 覆盖 beanDefinition 与 被覆盖的 beanDefinition 不相同,打印 debug 日志
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 其它,打印 debug 日志
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// *************允许覆盖,直接覆盖原有的 BeanDefinition 到 beanDefinitionMap 中*************
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// <4> 如果未存在
// 检测创建 Bean 阶段是否已经开启,如果开启了则需要对 beanDefinitionMap 进行并发控制
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 {
// 注册到容器中
this.beanDefinitionMap.put(beanName, beanDefinition);
// 注册beanName
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || containsSingleton(beanName)) {
// <5> 重新设置 beanName 对应的缓存
resetBeanDefinition(beanName);
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
-> registerAlias() 注册别名
把别名和beanName的映射关系添加到1个Map里面,key=别名,value=beanName
// SimpleAliasRegistry.java
@Override
public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
synchronized (this.aliasMap) {
// name == alias 则去掉alias
if (alias.equals(name)) {
this.aliasMap.remove(alias);
if (logger.isDebugEnabled()) {
logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
}
}
else {
// 获取 alias 已注册的 beanName
String registeredName = this.aliasMap.get(alias);
// 当注册的beanName存在
if (registeredName != null) {
// 相同,则 return ,无需重复注册
if (registeredName.equals(name)) {
// An existing alias - no need to re-register
return;
}
// 不允许覆盖,则抛出 IllegalStateException 异常
if (!allowAliasOverriding()) {
throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
name + "': It is already registered for name '" + registeredName + "'.");
}
if (logger.isDebugEnabled()) {
logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
registeredName + "' with new target name '" + name + "'");
}
}
// 校验,是否存在循环指向
checkForAliasCircle(name, alias);
// 注册 alias
this.aliasMap.put(alias, name);
if (logger.isTraceEnabled()) {
logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
}
}
}
}
允许覆盖,则抛出 IllegalStateException 异常
if (!allowAliasOverriding()) {
throw new IllegalStateException(“Cannot define alias '” + alias + “’ for name '” +
name + “': It is already registered for name '” + registeredName + “'.”);
}
if (logger.isDebugEnabled()) {
logger.debug(“Overriding alias '” + alias + “’ definition for registered name '” +
registeredName + “’ with new target name '” + name + “'”);
}
}
// 校验,是否存在循环指向
checkForAliasCircle(name, alias);
// 注册 alias
this.aliasMap.put(alias, name);
if (logger.isTraceEnabled()) {
logger.trace(“Alias definition '” + alias + “’ registered for name '” + name + “'”);
}
}
}
}