Spring 源码之 BeanDefinition 加载分析

什么是 BeanDefinition?

BeanDefinition 直译就是 bean 定义信息,BeanDefinition 是 Spring 用来描述一个 bean 的配置元信息的表现形式,bean 的各种配置元信息最后都会被转换为 BeanDefinition,Spring 会根据 BeanDefinition 去对 bean 进行实例化、初始化,BeanDefinition 涉及到 Spring Bean 的整个生命周期。

BeanDefinition 源码分析

AbstractApplicationContext#obtainFreshBeanFactory 源码分析

在 AbstractApplicationContext#refresh 方法的源码分析中,我们知道 obtainFreshBeanFactory 方法不仅创建了 BeanFactory,而且还挤在了 BeanDefinition,我们跟踪一下源码,如下:

//获取 DefaultListableBeanFactory beanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	//刷新 beanFactory
	this.refreshBeanFactory();
	//获取 beanFactory
	return this.getBeanFactory();
}

//刷新 beanFactory
protected final void refreshBeanFactory() throws BeansException {
	//beanFactory 判空
	if (this.hasBeanFactory()) {
	    //销毁单例bean
		this.destroyBeans();
		//关闭 beanFactory beanFactory 置为 null
		this.closeBeanFactory();
	}

	try {
	    //创建一个 beanFactory
		DefaultListableBeanFactory beanFactory = this.createBeanFactory();
		beanFactory.setSerializationId(this.getId());
		//设置一些属性 是否允许bean定义被覆盖 是否允许循环引用
		this.customizeBeanFactory(beanFactory);
		//加载beanBeanDefinition  本篇重点
		this.loadBeanDefinitions(beanFactory);
		this.beanFactory = beanFactory;
	} catch (IOException var2) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var2);
	}
}

根据源码我们知道 this.loadBeanDefinitions(beanFactory) 方法解析了 bean 定义,下面我们来分析一下这个方法,因为调用链路比较深,我们不做详细分析,只做重点代码解析。

this.loadBeanDefinitions(beanFactory) 源码分析

通过 idea 我们看到 loadBeanDefinitions 方法是由 AbstractRefreshableConfigApplicationContext 的实现类实现的,本文我们重点分析 AbstractXmlApplicationContext 实现逻辑

在这里插入图片描述

AbstractXmlApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 方法源码:

我们看到 AbstractXmlApplicationContext#loadBeanDefinitions 方法只是创建了一个 XmlBeanDefinitionReader 对象并进行初始化,并没有实际解析 bean 定义 。

//创建 XmlBeanDefinitionReader 对象并初始化
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    //创建 XmlBeanDefinitionReader 对象
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    //给 beanDefinitionReader 设置环境变量
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    //初始化 beanDefinitionReader
    this.initBeanDefinitionReader(beanDefinitionReader);
    //核心方法 加载 beanDefintion
    this.loadBeanDefinitions(beanDefinitionReader);
}

我们接着分析 AbstractXmlApplicationContext.loadBeanDefinitions((XmlBeanDefinitionReader reader) 方法

AbstractXmlApplicationContext#loadBeanDefinitions((XmlBeanDefinitionReader reader) 方法源码:

通过 AbstractXmlApplicationContext#loadBeanDefinitions((XmlBeanDefinitionReader reader) 方法源码我们知道这个方法其实也没有真正解析 bean 定义 xml 文件,也是一个封装方法。

//加载配置资源 加载 bean 定义 xml 文件
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
    //获取配置资源
    Resource[] configResources = this.getConfigResources();
    if (configResources != null) {
        //加载配置资源
        reader.loadBeanDefinitions(configResources);
    }
    //获取 xml 配置 Locations 也就是 classpath 下的
    String[] configLocations = this.getConfigLocations();
    if (configLocations != null) {
        //核心 解析 xml 配置文件中的 bean 定义 转换为 beanDefiniton 并注册到  BeanDefinitonRegistry
        reader.loadBeanDefinitions(configLocations);
    }

}

我们继续分析 AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String…) 方法

AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String…) 方法源码:

通过源码我们发现这个方法也并没有做什么实际的事情,只是循环遍历了 xml 文件地址,调用了 AbstractBeanDefinitionReader.loadBeanDefinitions(java.lang.String) 方法。

//对 xml 文件地址进行循环处理
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
    Assert.notNull(locations, "Location array must not be null");
    int count = 0;
    String[] var3 = locations;
    int var4 = locations.length;
    //循环处理 xml 文件地址
    for(int var5 = 0; var5 < var4; ++var5) {
        String location = var3[var5];
        //核心 解析 xml 文件为 beanDefintion
        count += this.loadBeanDefinitions(location);
    }
    //返回个数
    return count;
}

我们继续分析 AbstractBeanDefinitionReader#loadBeanDefinitions (java.lang.String) 方法。

AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String…) 方法源码:

//包装了一层 没有实际操作
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return this.loadBeanDefinitions(location, (Set)null);
}

我们继续分析 AbstractBeanDefinitionReader#loadBeanDefinitions(String location, @Nullable Set actualResources) 方法。

AbstractBeanDefinitionReader#loadBeanDefinitions(String location, @Nullable Set actualResources) 方法源码:

AbstractBeanDefinitionReader#loadBeanDefinitions(String location, @Nullable Set actualResources) 方法只是对不同模式的资源解析器进行了处理,最终都是调用了 AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource…)方法。

//根据资源加载器执行不同的 beandefinition 操作
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
    //获取资源加载器
    ResourceLoader resourceLoader = this.getResourceLoader();
    if (resourceLoader == null) {
        throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
    } else {
        int count;
        //资源解析器模式
        if (resourceLoader instanceof ResourcePatternResolver) {
            try {
                //有一组资源
                Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
                //核心方法
                count = this.loadBeanDefinitions(resources);
                if (actualResources != null) {
                    Collections.addAll(actualResources, resources);
                }

                if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
                }

                return count;
            } catch (IOException var6) {
                throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
            }
        } else {
            //单个资源
            Resource resource = resourceLoader.getResource(location);
            //核心方法
            count = this.loadBeanDefinitions((Resource)resource);
            if (actualResources != null) {
                actualResources.add(resource);
            }

            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
            }

            return count;
        }
    }
}

继续分析 AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource…)方法。

AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource…) 方法源码分析:

AbstractBeanDefinitionReader#loadBeanDefinitions 方法没有过多的操作,只是循环处理了传过来的 Resource,也是一个简单的方法封装。

//循环处理 获取到的 bean 定义 Resource
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int count = 0;
    Resource[] var3 = resources;
    int var4 = resources.length;

    for(int var5 = 0; var5 < var4; ++var5) {
        Resource resource = var3[var5];
        //核心方法
        count += this.loadBeanDefinitions((Resource)resource);
    }

    return count;
}

这里的 this.loadBeanDefinitions((Resource)resource) 有不同的实现,如下图:

在这里插入图片描述
我们继续分析 XmlBeanDefinitionReader 的实现 XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource) 方法。

XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource) 方法源码分析:

XmlBeanDefinitionReader#loadBeanDefinitions 并没有什么具体实现,还是一个方法封装,仅仅对 resource 进行了编码,就继续调用了 XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource) 方法。

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		//仅仅对 resource 进行了编码 核心方法
       return this.loadBeanDefinitions(new EncodedResource(resource));
}

XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource) 方法源码分析

千呼万唤始出来,我们终于要看到真正干活的方法了,也就是 XmlBeanDefinitionReader#doLoadBeanDefinitions (InputSource inputSource, Resource resource) 方法。

//加载 bean 定义信息
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
    Assert.notNull(encodedResource, "EncodedResource must not be null");
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Loading XML bean definitions from " + encodedResource);
    }

    Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
    if (!currentResources.add(encodedResource)) {
        throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    } else {
        int var6;
        try {
            //转换为输入流 此时我们的 xml 文件已经是流了
            InputStream inputStream = encodedResource.getResource().getInputStream();
            Throwable var4 = null;

            try {
                //sax 解析
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    //设置编码
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                //真正干活的方法来了  读过源码的都知道 Spring 中 do 开头的才是真正干活的方法
                var6 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            } catch (Throwable var24) {
                var4 = var24;
                throw var24;
            } finally {
                if (inputStream != null) {
                    if (var4 != null) {
                        try {
                            inputStream.close();
                        } catch (Throwable var23) {
                            var4.addSuppressed(var23);
                        }
                    } else {
                        inputStream.close();
                    }
                }

            }
        } catch (IOException var26) {
            throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var26);
        } finally {
            currentResources.remove(encodedResource);
            if (currentResources.isEmpty()) {
                //移出 防止内存泄漏
                this.resourcesCurrentlyBeingLoaded.remove();
            }

        }

        return var6;
    }
}

XmlBeanDefinitionReader#doLoadBeanDefinitions(InputSource inputSource, Resource resource)方法源码分析

XmlBeanDefinitionReader#doLoadBeanDefinitions 方法先把 InputSource 转换为 Document 文档对象,然后继续调用 XmlBeanDefinitionReader#registerBeanDefinitions 方法。

//真正加载 beandefinition 方法
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
    try {
        //将 inputSource 转换为 Document 文档对象
        Document doc = this.doLoadDocument(inputSource, resource);
        //核心方法 会根据解析出来的 document对象 拿到里面的标签元素封装成BeanDefinition
        int count = this.registerBeanDefinitions(doc, resource);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Loaded " + count + " bean definitions from " + resource);
        }

        return count;
    } catch (BeanDefinitionStoreException var5) {
        throw var5;
    } catch (SAXParseException var6) {
        throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
    } catch (SAXException var7) {
        throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
    } catch (ParserConfigurationException var8) {
        throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
    } catch (IOException var9) {
        throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
    } catch (Throwable var10) {
        throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
    }
}

XmlBeanDefinitionReader#registerBeanDefinitions(Document doc, Resource resource) 方法源码解析:

registerBeanDefinitions 方法主要是创建了 BeanDefinitionDocumentReader 用于读取文档 Document ,并且计算了本次解析之前的 bean 数量,最后返回本次真正解析的 bean 数量,真正解析的方法是 DefaultBeanDefinitionDocumentReader#registerBeanDefinitions。

//注册 beandefinition 其实就是从 Document 中解析 bean 定义标签
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    //创建 BeanDefinitionDocumentReader 用于读取文档
    BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
    //获取到解析之前的定义在 bean 工厂下面的bean的数量
    int countBefore = this.getRegistry().getBeanDefinitionCount();
    //真正的解析操作 使用 BeanDefinitionDocumentReader 来完成对 Document 中的 BeanDefinition 进行解析
    documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
    //现在解析完的减去已经解析过得bean 也就是当前实际解析的bean 的数量
    return this.getRegistry().getBeanDefinitionCount() - countBefore;
}

DefaultBeanDefinitionDocumentReader#registerBeanDefinitions (Document doc, XmlReaderContext readerContext) 方法源码分析:

registerBeanDefinitions 方法并没有什么实际操作,只是获取了 Document 的 Element,然后接着调用了 DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions 方法。

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        this.doRegisterBeanDefinitions(doc.getDocumentElement());
}

DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions(Element root) 方法源码分析:

doRegisterBeanDefinitions 方法基本也没有做什么操作,也是对方法进行了封装,调用了DefaultBeanDefinitionDocumentReader#parseBeanDefinitions 方法。

//注册 beandefinition 
protected void doRegisterBeanDefinitions(Element root) {
    //创建 bean 定义解析器
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
    if (this.delegate.isDefaultNamespace(root)) {
        String profileSpec = root.getAttribute("profile");
        if (StringUtils.hasText(profileSpec)) {
            String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
            if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
                }

                return;
            }
        }
    }
    //预处理 xml 空方法 可以自己扩展
    this.preProcessXml(root);
    //关键中的关键方法 真正的解析 bean 定义的方法来了
    this.parseBeanDefinitions(root, this.delegate);
    //后处理 xml  空方法 可以自己扩展
    this.postProcessXml(root);
    this.delegate = parent;
}

DefaultBeanDefinitionDocumentReader#parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) 方法源码解析:

parseBeanDefinitions 方法先是获取元素的所有子节点,对子节点进行遍历处理,如果是默认名称空间就是用默认解析器进行解析,否则自定义解析,我们继续看 DefaultBeanDefinitionDocumentReader#parseDefaultElement 方法。

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
        //获取所有子节点
        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)) {
                    //核心方法 解析 bean
                    this.parseDefaultElement(ele, delegate);
                } else {
                    //不是默认名称空间 自定义解析 bean
                    delegate.parseCustomElement(ele);
                }
            }
        }
    } else {
        delegate.parseCustomElement(root);
    }

}

DefaultBeanDefinitionDocumentReader#parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) 方法源码解析:

parseDefaultElement 方法就是针对不同的标签调用了不同的方法,也使用了 if else 的写法(哈哈哈哈),我们继续关注 DefaultBeanDefinitionDocumentReader#processBeanDefinition 方法。

//解析默认元素 这个方法就很容易读懂了
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, "import")) {
         //解析 import 标签
        this.importBeanDefinitionResource(ele);
    } else if (delegate.nodeNameEquals(ele, "alias")) {
         //解析 alias 标签
        this.processAliasRegistration(ele);
    } else if (delegate.nodeNameEquals(ele, "bean")) {
         //解析 bean 标签 我们本次要关注的
        this.processBeanDefinition(ele, delegate);
    } else if (delegate.nodeNameEquals(ele, "beans")) {
         //解析 beans 标签
        this.doRegisterBeanDefinitions(ele);
    }

}

DefaultBeanDefinitionDocumentReader#processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) 方法源码解析:

processBeanDefinition 方法主要是解析 Element 得到 BeanDefinitionHolder ,并调用 BeanDefinitionReaderUtils#registerBeanDefinition 方法将 BeanDefinitionHolder 注册到 BeanDefinitionRegistry 中,我们继续看 BeanDefinitionReaderUtils#registerBeanDefinition 方法。

//处理bean 定义
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    //解析bean 定义 并返回一个 bean 定义持有者   BeanDefinitionHolder  应该都听说过
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        //装饰 BeanDefinitionHolder
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

        try {
            //注册 beandefinition 将上面解析到的 BeanDefinitionHolder 注册到 BeanDefinitionRegistry 中
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
        } catch (BeanDefinitionStoreException var5) {
            this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
        }

        this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }

}

BeanDefinitionReaderUtils#registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) 方法源码解析:

registerBeanDefinition 方法就真正开始注册 Beandefinition 了,将 Beandefinition 注册到 BeanDefinitionRegistry 中,我们继续跟一下 DefaultListableBeanFactory#registerBeanDefinition 方法(DefaultListableBeanFactory 貌似又看到了熟悉的朋友)。

//注册 beandefinition
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
    //获取beanName
    String beanName = definitionHolder.getBeanName();
    //将beandefinition 注册到 BeanDefinitionRegistry 中
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        String[] var4 = aliases;
        int var5 = aliases.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String alias = var4[var6];
            registry.registerAlias(beanName, alias);
        }
    }

}

DefaultListableBeanFactory#registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法源码分析:

registerBeanDefinition 方法完成了 BeanDefinition 的注册,我们看到了熟悉的 BeanDefinitionMap,至此 BeanDefinition 注册已经完成了。

//注册 BeanDefinition
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 var9) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
        }
    }

    //beanDefinitionMap 中是否有当前beandefinition
    BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
    //判断当前 beandefinition 是否注册过
    if (oldBeanDefinition != null) {
        if (!this.isAllowBeanDefinitionOverriding()) {
            //注册过 不允许覆盖 抛出异常
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
        }

        if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
            if (this.logger.isWarnEnabled()) {
                this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }
        } else if (!beanDefinition.equals(oldBeanDefinition)) {
            if (this.logger.isInfoEnabled()) {
                this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }
        } else if (this.logger.isDebugEnabled()) {
            this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
        }
        //放入 beanDefinitionMap
        this.beanDefinitionMap.put(beanName, beanDefinition);
    } else {
        //没有注册过 注册 beandeifinition
        if (this.hasBeanCreationStarted()) {
            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;
                if (this.manualSingletonNames.contains(beanName)) {
                    Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        } else {
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }

        this.frozenBeanDefinitionNames = null;
    }

    if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
        this.resetBeanDefinition(beanName);
    }

}

总结:我们简单的分析了 BeanDefinition 的加载流程,整个调用链路相比较我们平时写业务代码还是比较深的,每个方法的只职能清晰,值得我们借鉴学习,流程分析的比较粗糙,只是大概分析了 BeanDefinition 加载的核心点,希望可以帮助到有需要的小伙伴。

欢迎提出建议及对错误的地方指出纠正。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring 6中的BeanDefinition是指在Spring容器中定义和配置的一个实例化对象的元数据。它描述了要创建的对象的属性、构造函数参数和其他配置信息。 BeanDefinition包含了以下重要的属性: 1. Bean的Class:指定要创建的对象的类。 2. Bean的作用域(Scope):指定对象的生命周期管理方式,包括Singleton、Prototype、Request、Session等。 3. Bean的依赖关系:指定对象之间的依赖关系,即其他Bean定义的引用。 4. Bean的初始化和销毁方法:指定对象初始化时执行的方法和销毁时执行的方法。 5. Bean的属性值和引用:指定对象的属性值,可以是基本类型值或其他Bean的引用。 6. Bean的构造函数参数:指定实例化对象时传递给构造函数的参数。 通过配置BeanDefinitionSpring容器能够根据这些元数据来创建和管理Bean实例。在容器启动时,会解析并根据BeanDefinition来实例化对象,并进行必要的依赖注入、初始化和销毁操作。每个BeanDefinition都代表了一个独立的对象定义,通过指定不同的属性值和配置,可以创建不同的对象实例。 BeanDefinition的配置可以使用XML、注解或Java Config等方式进行。使用Spring的IoC容器可以很方便地管理和配置大量的BeanDefinition,使得开发人员能够更灵活和高效地控制对象的创建和管理。 总之,BeanDefinitionSpring框架用于描述和配置对象实例化的元数据,通过配置BeanDefinition,可以对对象的属性、依赖关系、作用域等进行管理和配置,从而实现灵活的对象创建和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值