Spring源码解析之推断构造方法

标题:Spring源码解析之推断构造方法

前言

在Spring的IoC容器中,我们可以使用自动装配的方式注入Bean实例,Spring会根据构造方法参数的类型和名称来自动匹配注入对应类型的实例。Spring是如何实现自动装配的呢?从源码层面解析,自动装配的核心就是推断构造方法。

推断构造方法

Spring会尝试推断某个Bean的构造方法,根据该构造方法参数类型和名称匹配注入对应类型的实例。推断构造方法的策略分为三个步骤:

  1. 查找构造方法列表,获取所有public访问修饰符的构造器;
  2. 选取合适的构造方法;
  3. 利用选中的构造方法进行实例化。

查找构造方法列表

在获取构造方法列表时,Spring会使用Class.getConstructors()方法获取当前类的所有构造器,并将其封装在Constructor数组中返回。示例代码如下:

//获取构造方法列表
Constructor<?>[] constructors = beanClass.getConstructors();

选取合适的构造方法

在获取构造方法列表之后,Spring会尝试选取合适的构造方法。选取构造方法的策略如下:

  1. 构造方法的参数个数最少的优先选取;
  2. 构造方法中参数类型与其他Bean的类型有直接依赖关系的优先选取;
  3. 若以上两点都无法确定,则选择第一个构造方法。

需要注意的是,只有在Bean的定义中没有明确指定构造方法的方式时,Spring才会尝试推断构造方法。示例代码如下:

//选取合适的构造方法
Constructor<?> constructorToUse = beanDefinition.constructorToUse;
if (constructorToUse == null) {
    for (Constructor<?> constructor : constructors) {
        ...
    }
}

利用构造方法进行实例化

在选取合适的构造方法之后,Spring会使用该构造方法创建一个新的Bean实例。示例代码如下:

//实例化Bean
Object[] argsToUse = determineConstructArguments(beanName, beanDefinition, selectedValues);
beanInstance = BeanUtils.instantiateClass(constructorToUse, argsToUse);

示例说明

示例1

有一个DemoController类,声明了两个依赖,分别是DemoService和DemoRepository:

@Controller
public class DemoController {

    private final DemoService demoService;

    private final DemoRepository demoRepository;

    public DemoController(DemoService demoService, DemoRepository demoRepository) {
        this.demoService = demoService;
        this.demoRepository = demoRepository;
    }

    ...
}

在使用自动装配的方式将DemoService和DemoRepository注入DemoController时,Spring会自动推断构造方法,并选取构造方法来实例化Bean对象,示例代码如下:

<bean id="demoService" class="com.example.DemoService" />
<bean id="demoRepository" class="com.example.DemoRepository" />
<bean id="demoController" class="com.example.DemoController" autowire="constructor" />

示例2

有一个DemoService类,声明了一个依赖,注入了一个DemoDao:

@Service
public class DemoService {

    private final DemoDao demoDao;

    public DemoService(DemoDao demoDao) {
        this.demoDao = demoDao;
    }

    ...
}

在使用自动装配的方式将DemoDao注入DemoService时,Spring会自动推断构造方法,并选取构造方法来实例化Bean对象,示例代码如下:

<bean id="demoDao" class="com.example.DemoDao" />
<bean id="demoService" class="com.example.DemoService" autowire="constructor" />

结语

本文从源码层面分析了Spring自动装配的核心——推断构造方法的实现策略,希望对理解Spring源码和使用Spring框架有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring源码解析之推断构造方法 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • win7下配置GO语言环境 + eclipse配置GO开发

    1. 配置GO语言环境 1.1 下载GO语言安装包 去https://golang.google.cn/dl/ ,根据自己的操作系统版本下载对应的安装包。 示例:下载Windows 64位的安装包。 1.2 安装GO语言 双击安装包,按照提示一步一步安装即可。安装完成后,检查系统环境变量中是否已经配置好了GOPATH。 示例:在安装过程中,按照默认设置来安装…

    other 2023年6月27日
    00
  • ActionScript的API文档生成工具ASDoc

    ASDoc是一种基于ActionScript语言的API文档生成工具,可以通过注释生成完整的文档,方便其他开发者阅读和使用代码。下面是ASDoc的详细攻略: 1. 安装ASDoc ASDoc是一个单独的工具包,需要手动安装。可以将其下载下来,然后将ASDoc.exe放入到Flex SDK的bin目录下。 2. 编写代码注释 在代码中编写好注释是使用ASDoc…

    other 2023年6月26日
    00
  • 内存不够用如何增加电脑的虚拟内存(xp/win7)

    当电脑的内存不够用时,可以通过增加虚拟内存来提升系统的性能。虚拟内存是指操作系统将硬盘空间用作内存扩展的一种技术。在Windows XP和Windows 7操作系统中,可以按照以下步骤增加电脑的虚拟内存: 打开“控制面板”:点击开始菜单,选择“控制面板”。 进入“系统”设置:在控制面板中,找到并点击“系统”选项。 进入“高级系统设置”:在系统窗口中,点击左侧…

    other 2023年8月1日
    00
  • linux下解决 git clone每次都要输入用户名密码问题(推荐)

    下面是“linux下解决 git clone每次都要输入用户名密码问题(推荐)”的完整攻略。 问题背景 通过 git clone 命令拉取某个项目的代码时,如果使用的是 HTTPS 协议,那么每次都要输入用户名和密码,这给我们带来很大的不便。 解决方案 解决这个问题的方法有很多种,其中最为推荐的是使用 SSH 协议进行代码拉取。在使用 SSH 协议之前,我们…

    other 2023年6月27日
    00
  • ASP.NET在线文本编辑控件的使用(第6节)

    当我们在开发网站或者Web应用的时候,常常需要提供文本编辑的功能,比如输入文本、编辑、格式化等等。而ASP.NET提供了一种在线文本编辑控件,可以非常方便的实现这些功能。 下面是ASP.NET在线文本编辑控件的使用攻略: 1. 安装在线文本编辑控件 首先,在NuGet上搜索“TinyMCE”,并安装最新版本的在线文本编辑控件。 在Visual Studio的…

    other 2023年6月27日
    00
  • log4j配置文件详解

    log4j配置文件详解 Log4j是一款开源的Java日志框架,可以帮助Java应用程序记录和管理日志。在使用Log4j时,必须通过配置文件进行配置,以定义日志输出方式、日志级别和格式等。本文将给出一个Log4j配置文件的详细解释。 配置文件命名 Log4j的配置文件一般命名为log4j.properties或者log4j.xml,其中properties文…

    其他 2023年3月28日
    00
  • Java类初始化执行流程解析

    下面我来详细讲解Java类初始化执行流程解析的完整攻略。 Java类初始化执行流程解析 在Java中,类初始化是Java程序中的一个重要的概念,因为在Java程序运行时,只要有类被使用了,就会触发类的初始化。类初始化这个过程对Java程序的运行至关重要,因此,我们有必要深入了解Java类初始化执行过程,以便更好地理解Java程序运行过程。 一、类初始化的触发…

    other 2023年6月20日
    00
  • 关于jdk环境变量配置以及javac不是内部或外部命令的解决

    关于JDK环境变量配置以及javac不是内部或外部命令的解决有以下攻略: 配置JAVA_HOME环境变量 前往Oracle官网下载对应版本的JDK,例如jdk-11.0.4_windows-x64_bin.exe 打开安装文件,按照提示进行安装,注意安装路径,以jdk-11.0.4为例,默认路径为C:\Program Files\Java\jdk-11.0.…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部