Spring 源码阅读 09:加载 BeanDefinition 的过程(注册阶段)

Spring IOC学习(6)——DefaultListableBeanFactory DefaultListableBeanFactory已经是一个成熟的容器了,是Spring的默认BeanFactory 阅读详情

向容器中注册 BeanDefinition

这部分从 DefaultBeanDefinitionDocumentReader 中的processBeanDefinition方法说起:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   if (bdHolder != null) {
      bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      try {
         // 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));
   }
}

在解析完成之后,负责将 BeanDefinition 注册到容器中的是这样代码:

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

 

传入方法的参数,一个是之前解析道的 BeanDefinitionHolder,另一个其实就是我们最初创建的 BeanFactory(这里为什么是最初创建的 BeanFactory ?分析如下:)。

这里的registry就是我们起初创建的 BeanFacoty,之前涉及到的流程已经很多了,这里再捋一下起初创建的 BeanFacoty 是怎么到这儿的。

  • 在AbstractApplicationContext的refresh方法中,调用了obtainFreshBeanFactory方法,其中的refreshBeanFactory方法通过createBeanFactory方法创建了一个 DefaultListableBeanFactory,并赋值给了beanFactory成员变量。
  • 在解析 XML 文件之前,AbstractXmlApplicationContext的loadBeanDefinitions方法中,创建 XmlBeanDefinitionReader 的时候,通过构造方法,将beanFactory赋值给了其registry成员变量,这一步通过其父类 AbstractBeanDefinitionReader 的构造方法完成。
  • 在 XmlBeanDefinitionReader 的registerBeanDefinitions方法中,通过createBeanDefinitionDocumentReader方法创建了 DefaultBeanDefinitionDocumentReader 类型的变量documentReader,并在调用documentReader的registerBeanDefinitions方法时,通过createReaderContext创建了一个 XmlReaderContext 作为方法的参数传递给了documentReader并赋值给了其readerContext成员变量。
  • 上一步中,createReaderContext方法中,将当前对象也就是 XmlBeanDefinitionReader 对象作为参数传入并赋值给了reader成员变量,而 DefaultBeanDefinitionDocumentReader 调用getReaderContext().getRegistry()方法的时候,getReaderContext获取到的是之前创建的 XmlReaderContext 对象,getRegistry方法实际逻辑是this.reader.getRegistry(),其中的this.reader就是 XmlBeanDefinitionReader,因为 XmlBeanDefinitionReader 的beanFactory成员变量就是起初创建的 BeanFactory。
  • 因此这里得到的就是最初创建的BeanFactory

我们跳进方法里看源码:

public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {

   // 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);
      }
   }
}

这里的关键步骤是registry.registerBeanDefinition方法的调用。也就是 DefaultListableBeanFactory 中的registerBeanDefinition方法:

@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");

   // 第一部分,对 BeanDefinition 进行注册前的检查
   if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
         ((AbstractBeanDefinition) beanDefinition).validate();
      }
      catch (BeanDefinitionValidationException ex) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Validation of bean definition failed", ex);
      }
   }

   // 第二部分,注册 BeanDefinition
   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("...");
         }
      }
      else if (!beanDefinition.equals(existingDefinition)) {
         if (logger.isDebugEnabled()) {
            logger.debug("...");
         }
      }
      else {
         if (logger.isTraceEnabled()) {
            logger.trace("...");
         }
      }
      this.beanDefinitionMap.put(beanName, beanDefinition);
   }
   else {
      if (hasBeanCreationStarted()) {
         // Cannot modify startup-time collection elements anymore (for stable iteration)
         synchronized (this.beanDefinitionMap) {
            this.beanDefinitionMap.put(beanName, beanDefinition);
            List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
            updatedDefinitions.addAll(this.beanDefinitionNames);
            updatedDefinitions.add(beanName);
            this.beanDefinitionNames = updatedDefinitions;
            removeManualSingletonName(beanName);
         }
      }
      else {
         // Still in startup registration phase
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }

   if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   }
   else if (isConfigurationFrozen()) {
      clearByTypeCache();
   }
}

以上两个方法就是注册 BeanDefination 的整个流程,代码比较长,先大概捋一下流程,再分开详细讲解。在代码里我通过注释把代码大体分为两部分:

  1. 对 BeanDefinition 进行注册前的检查
  2. 注册 BeanDefinition

下面分别深入分析。

注册前的检查

这部分涉及到的代码主要是validate方法的调用:

public void validate() throws BeanDefinitionValidationException {
   if (hasMethodOverrides() && getFactoryMethodName() != null) {
      throw new BeanDefinitionValidationException("...");
   }
   if (hasBeanClass()) {
      prepareMethodOverrides();
   }
}

先看第一个if语句的判断条件。

  • hasMethodOverrides()方法获取到的是!this.methodOverrides.isEmpty()。这里简单介绍一下methodOverrides是什么。在将 XML 配置解析成 BeanDefinition 的时候,bean标签的lookup-method和replaced-method会被分别解析成 LookupOverride 和 ReplaceOverride 对象,添加到 BeanDefinition 的methodOverrides成员变量中。它们的作用是通过配置来覆盖 Bean 原有的方法实现。
  • getFactoryMethodName()获取到的是 XML 在bean标签上配置的用来创建 Bean 的工厂方法。

这个if语句是为了确保,上述两者不能共存,否则就会报错。这是因为,如果给一个 Bean 配置了工厂方法,那么它会由工厂方法来创建,而不是 Spring 默认的方式创建,这种情况下无法进行方法的覆盖。因此,这里的判断是为了确保配置信息没有出现冲突。

再看第二个if语句,判断条件hasBeanClass()在我们分析的流程中肯定会返回true,因此我们直接看语句块中的prepareMethodOverrides()方法调用。

public void prepareMethodOverrides() throws BeanDefinitionValidationException {
   // Check that lookup methods exist and determine their overloaded status.
   if (hasMethodOverrides()) {
      getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
   }
}

protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
   int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
   if (count == 0) {
      throw new BeanDefinitionValidationException("");
   }
   else if (count == 1) {
      // Mark override as not overloaded, to avoid the overhead of arg type checking.
      mo.setOverloaded(false);
   }
}

这里针对配置了 MethodOverrides 的 BeanDefinition,从 Bean 对应的类中获取同名的方法,也就是要被覆盖的方法。

如果找不到,则报错,因为这算是一个配置错误。

如果需要被覆盖的方法同名方法在类中之存在 1 个,说明在类中没有它的重载方法,则将 MethodOverride 的overloaded属性设置为false。这一步是为了告诉 Spring 在覆盖方法的时候,不需要再去检查 Bean 中是否有其他的重载方法了,算是一个性能上的优化。

注册 BeanDefinition

接下来回到 DefaultListableBeanFactory 的registerBeanDefinition方法的第二部分,开始进入注册 BeanDefinition 的流程。

首先,会从beanDefinitionMap容器中根据当前 BeanDefinition 中配置的beanName查找已经存在的 BeanDefinition:

BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);

因为我们这里分析的是初始化的流程,beanDefinitionMap应该是空的,所以这里是获取不到已有的 BeanDefinition 的,并且目前是注册 BeanDefinition 的阶段,Bean 的创建也没有开始,所以,我们可以省略掉对应的逻辑,直接看注册的逻辑:

// 第二部分,注册 BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
  /*  前已经存在同名的 BeanDefinition 的逻辑*/
}
else {
  if (hasBeanCreationStarted()) {
     /* 已经开始 Bean 创建的逻辑 */
  }
  else {
     // Still in startup registration phase
     this.beanDefinitionMap.put(beanName, beanDefinition);
     this.beanDefinitionNames.add(beanName);
     removeManualSingletonName(beanName);
  }
  this.frozenBeanDefinitionNames = null;
}

这里就很简单了,将beanDefinition和beanName分别添加到对应的集合中即可。

处理别名

DefaultListableBeanFactory 的registerBeanDefinition方法执行完之后,又会回到 BeanDefinitionReaderUtils 的registerBeanDefinition中的后半部分代码:

// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
  for (String alias : aliases) {
     registry.registerAlias(beanName, alias);
  }
}

可以看出这里的流程是为了处理 BeanDefinition 的别名,我们跳到registerAlias方法去看一下,根据 DefaultListableBeanFactory 的继承关系,这个方法的实现可以在 SimpleAliasRegistry 中找到:

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) {
      if (alias.equals(name)) {
         this.aliasMap.remove(alias);
         if (logger.isDebugEnabled()) {
            logger.debug("...");
         }
      }
      else {
         String registeredName = this.aliasMap.get(alias);
         if (registeredName != null) {
            if (registeredName.equals(name)) {
               // An existing alias - no need to re-register
               return;
            }
            if (!allowAliasOverriding()) {
               throw new IllegalStateException("...");
            }
            if (logger.isDebugEnabled()) {
               logger.debug("...");
            }
         }
         checkForAliasCircle(name, alias);
         this.aliasMap.put(alias, name);
         if (logger.isTraceEnabled()) {
            logger.trace("...");
         }
      }
   }
}

方法中的逻辑如下:

  1. 如果beanName和别名相同,则将别名从aliasMap中移除
  2. 根据别名从aliasMap找到对应的beanName
    1. 如果可以找到,说明之前注册过了,直接返回,不执行后面的逻辑
    2. 如果找不到,就判断是不是允许别名覆盖,不允许就抛出异常
  3. 检查别名循环
  4. 将别名和beanName的对应关系添加到aliasMap中(包括允许覆盖的情况)

整体逻辑比较简单,下面看一下检查别名循环的方法checkForAliasCircle:

protected void checkForAliasCircle(String name, String alias) {
   if (hasAlias(alias, name)) {
      throw new IllegalStateException("Cannot register alias '" + alias +
            "' for name '" + name + "': Circular reference - '" +
            name + "' is a direct or indirect alias for '" + alias + "' already");
   }
}

public boolean hasAlias(String name, String alias) {
   String registeredName = this.aliasMap.get(alias);
   return ObjectUtils.nullSafeEquals(registeredName, name) || (registeredName != null
         && hasAlias(name, registeredName));
}

这里的逻辑也比较简单,举个例子就是,检查是不是存在一个beanName是a别名是b的 Bean,同时又存在一个beanName是b别名是a的Bean。如果有就抛出异常。

后续

至此,Spring 加载 BeanDefinition 的过程就全部分析完了,可以说这是 BeanFactory 初始化过程中最复杂的步骤。初始化完 BeanFactory 之后,就有了一个初级的容器。

STM32 驱动直流无刷电机(BLDC)发声 阅读详情

相关推荐

Mem0 vs LangMem vs Letta:三大AI记忆框架实战对比(附代码示例)

本文深入对比了Mem0、LangMem和Letta三大AI记忆框架的核心特性与适用场景。Mem0提供开箱即用的记忆管理服务,适合快速集成;LangMem深度融入LangGraph生态,适合复杂工作流;Letta则采用虚拟内存系统,旨在突破上下文窗口限制。文章通过实战代码示例,为开发者选择适合其业务需求的AI记忆解决方案提供了清晰指南。

g9h0i1的博客 681

spring5源码篇(2)——BeanDefinition的注册

spring5源码篇之BeanDefinition的注册

笔记罢了 1740

Android GNSS 可视卫星星空图/卫星天顶图 原理及画法介绍

目录1 概念介绍2 绘制步骤2.1 获取卫星信息2.2 绘制底图 效果图: 1 概念介绍 首先介绍一下方位角和高度角的概念: 方位角:是从某点的指北(地理北极)方向线起,依顺时针方向到目标方向线之间的水平夹角。 高度角:从一点至观测目标的方向线与水平面间的夹角。 卫星天顶图 即是根据每一颗卫星的方位角和高度角将其画在以观测位置为中心的天顶图上。 天顶图其底图为由外向内的三个圆和四条直线。三个圆由外向内依次代表高度角0°、30°、60°,中心点代表90°;四条直线分别表示正北-正南、东北-西南、正东

x1471898145的博客 1万+

registerBeanDefinition

public interface BeanDefinitionRegistry extends AliasRegistry { /** * 在此注册表中注册一个新的bean定义。必须支持RootBeanDefinition和ChildBeanDefinition。 * @param beanName 要注册的bean实例的名称 * @param beanDefinition 要注册的bean实例的定义 *指定的bean名称,我们不允许覆盖它 * @see GenericBeanDe.

zzzzzyyyz的博客 2234

基因的富集分析

通过RNA_seq差异表达分析等获得一组基因,想要进一步了解这些基因可能参与哪些生物学过程,具有哪些功能,一般就会用到基因的富集分析了。现在小麦基因注释信息已经可以获得,目前来看包括两套。一个是TGACv1,另一个就是IWGSC1.0。需要用到一个叫“clusterProfiler”的R包。下面用到的数据集来自TGACv1。1、安装source("https://bioconductor.org/b

xxxxx 1万+

【Python搞定车载自动化测试】——Python实现车载以太网DoIP刷写(含Python源码)

随着智能电动汽车行业的发展,汽车=智能终端+四个轮子,而人工智能也发展越来越快,Python语言使用越来越广,本章节主要介绍如何使用Python语言基于Pytest自动化框架来实现DoIP诊断自动化测试。首先回顾一下DoIP诊断基础知识:DoIP(Diagnosis over Internet Protocol)是一种用于车辆诊断的网络通信协议。它基于现代互联网技术,允许通过以太网或IP网络进行车辆诊断和通信。

测试领域技术分享 3797

【小白的Spring源码手册】 Bean的扫描、装配和注册,面试学习可用

了解Spring框架的IoC容器内容,了解@Component、Scope、Lazy、Primary、DependsOn等注解被如何使用。学习Bean的扫描、装配到完成注册的整个流程。

HO1_K的博客 920

【STM32项目】基于stm32智能鱼缸控制系统的设计与实现(完整工程资料源码)

随着现代化经济的快速发展,物质条件富足的人开始追求精神富足,越来越多的人通过饲养观赏鱼来充实生活、释放压力,但并非所有饲养者都有时间和经验来管理好鱼缸。一种由单片机控制,可实时检测和调节鱼缸环境,可把鱼缸环境实时反映给用户并能被用户远程操控的系统,可以解决养鱼成活率低、耗费时间和精力、参与感不强等诸多难题。

嵌入式技术开发 7354

Spring框架探索二(BeanDefinition的扫描注册)

一、下图为简单的扫描注入过程时序图 二、扫描注入过程具体代码 ​ spring的依赖注入是从SpringApplication的refreshContext(context)方法开始,具体流程如下; @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 刷新前准备,close和active标

qq_35015148的博客 397

30、模态组合规则在振动分析中的应用

本文详细介绍了模态组合规则在振动分析中的应用,重点讨论了绝对峰值叠加法(SRSS)和完全二次组合(CQC)的理论基础、应用场景及优缺点。通过具体工程实例,展示了模态组合规则在地震载荷下结构响应分析中的实际效果,并提供了应用步骤和注意事项,为结构设计和安全评估提供了科学依据。

nice1的博客 222

一键开关机电路

一键开关机电路

让你爱上电路设计 4181

Spring源码解析系列汇总

相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题。喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源码解析的demo环境,启动这个环境即可开启阅读Spring源码的第一步 开始源码阅读时介绍了Spring容器中最经典的容器ClassPathXmlApplicationContext,这个...

Java学习录 1459

基于 ESP32-CAM 与 TinyML 的食堂餐盘自动识别与营养分析终端

【代码】基于 ESP32-CAM 与 TinyML 的食堂餐盘自动识别与营养分析终端。

weixin_42300449的博客 167

Spring源码学习--AbstractAutowireCapableBeanFactory.createBean

2019-09-23阅读1K0 记得跟老婆谈恋爱时,女儿心血来潮给老婆做饭,按照菜谱先一步的做,结果点差把厨房厨房 入口 上一篇,AbstractBeanFactory.getBean 的主流程,今天介绍下其中的createBean方法,程序入口如下: <span style="color:#333333"><span style="color:#333333"><span style="background-color:#50556b"&gt...

u014191624的博客 488

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Java面试全攻略:从基础到分布式,助你实现50%薪资涨幅

Java作为企业级应用开发的核心语言,其技术体系涵盖从基础语法到分布式架构的完整知识栈。理解Java虚拟机(JVM)的内存模型和垃圾回收机制是性能优化的基础,而并发编程中的线程安全、锁机制则是构建高可用系统的关键。这些核心技术不仅决定了应用的稳定性和效率,更在电商、金融等高频交易场景中发挥着重要作用。针对金九银十招聘季,本文基于高频面试题和实战经验,系统梳理了Java基础、JVM调优、MySQL优化等核心考点,帮助开发者通过科学的准备方法提升面试通过率。攻略特别关注并发编程和分布式系统设计等难点,为1-5年

weixin_34220179的博客 301

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

DefaultListableBeanFactory

Springboot启动场景 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefin

qq_44587855的博客 528

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Spring启动之bean定义注册

1、前言 Spring容器在本文可以简单理解为DefaultListableBeanFactory,它是BeanFactory的实现类,这个类有几个非常重要的属性:beanDefinitionMap是一个map,用来存放bean所对应的BeanDefinition;beanDefinitionNames是一个List集合,用来存放所有bean的name;singletonObjects是一个Map,用来存放所有创建好的单例Bean 2、入口 2.1、主方法 public static void main

InterceptWall的博客 1310

Spring源码解析之getBean(beanName)

Spring之getBean(name)方法源码解析

Lucifer ZHAO 2220

Spring中Bean注入源码分析

抽象的思想:在BeanDefinition的实现和Bean的实现逻辑中,都完成高度抽象并且遵循单一原则和高度抽象,代码的可扩展性和复用性很高,我们作为开发者也可以通过Spring暴露的各种Registry接口实现对Bean的操作。容器化思想:从BeanDefinition和Bean的注入来看,整个的实现思路都是基于容器化思想来实现的,将开发中需要关心的对象都实例化到容器中,开发者在使用时只要从容器中获取即可,并且获取bean的方式也很灵活,开发者在使用和扩展性上更便利。封装、继承、多态。

m0_71777195的博客 751

Spring的IOC依赖的处理方式的演示

前言:spring在getBean的时候,能够自动处理加载依赖的bean,即先实例化初始化依赖bean,然后再实例化本bean,这个过程中依赖以及循环依赖的校验是怎么处理的,我们用一个小案例进行演示。 1、概述 我们自制一个集BeanDefinition注册,bean实例化,依赖校验和依赖关系注册等等一系列功能为一体的BeanFacotry,即把spring继承各种接口的功能基于一体的BeanFaoctry(DefaultListableBeanFactory)。首先这个BeanFactory需要有能够

shuixiou1的博客 335

spring源码(8)注册解析的BeanDefinition

对于配置文件解析完之后,我们得到了beanDefinition。下一步就是注册。 同样,注册操作委托给BeanDefinitionReaderUtils.registerBeanDefinition。public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDef

Programming is an art form. 599

Spring的Bean定义注册中心BeanDefinitionRegistry详解

如果想注册到spring容器,让spring来完成实例化,常用方式如下:xml中通过bean节点来配置;使用@Service、@Controller、@Conponent等注解;详见Spring注解驱动开发—向Spring Ioc容器中注册Bean的7种方式。

tian830937的专栏 1353

sping-bean

spring-bean的创建过程 创建bean的方法 /** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */ @Override protected Object createBean(String beanName, RootBeanDefinition mbd,

craywen的博客 186

Spring IoC的细节--BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element ele)

//解析Bean定义资源Document对象的普通元素 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //将Element元素--->BeanDefinition的过程在此 //对Document对象中<Bean>元素的解析由...

aidaowuqiong的博客 693

spring内幕(五)容器的初始化过程之BeanDefinition的注册

前面找到resource ,然后又解析到BeanDefinition之后,接下来要将BeanDefinition注册到容器中。 注册就比较简单了,其触发地点在DefaultBeanDefinitionDocumentReader的processBeanDefinition中 该方法就是 delegate.parseBeanDefinitionElement(ele)解析元素, 然后BeanDef...

hello world 754

spring 源码个人浅浅分析(2)---MethodOverrides详解

MethodOverrides方法的覆盖源码分析 如下xml配置: <bean id="getBeanTest" class="springSourseAnalyes.GetBeanTest" lazy-init="true"> <lookup-method name="getBean" bean="stu" /> </bean> <b...

cuichunchi的博客 4188
上一篇: 8分钟,复习一遍红黑树!
下一篇: Spring Cloud集成Nacos作为注册中心
java_lujj
博客等级 码龄4年 18粉丝 152原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值