当前位置: 首页 > article >正文

16. Spring源码篇之指定构造方法参数

简介

为什么讲这个,是因为在spring使用构造方法注入的时候会有大量的判断,是不是指定了参数。如果指定了参数就可以使用不同的构造方法去实例化Bean,本文将介绍如何指定参数

使用

首先看一个例子

// 定义三个构造函数
public class UserBean implements UserGenerics {

    public UserBean() {
        System.out.println("无参构造函数");
    }

    public UserBean(String name) {
        System.out.println("一个参数 name=" + name);
    }

    public UserBean(String name, int age) {
        System.out.printf("两个参数 name=%s,age=%s", name, age);
    }

}

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
    
    // 注册一个userBean1,指定有一个参数
    beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("shura");
    beanDefinition.setBeanClass(UserBean.class);
    context.registerBeanDefinition("userBean1", beanDefinition);

    // 注册一个userBean2,指定有两个参数
    GenericBeanDefinition beanDefinition2 = new GenericBeanDefinition();
    beanDefinition2.getConstructorArgumentValues().addIndexedArgumentValue(0, "shura");
    beanDefinition2.getConstructorArgumentValues().addIndexedArgumentValue(1, 20);
    beanDefinition2.setBeanClass(UserBean.class);
    context.registerBeanDefinition("userBean2", beanDefinition2);
    
    context.refresh();
}

执行上面代码输出

一个参数 name=shura
两个参数 name=shura,age=20

可见,源码肯定是有这些判断逻辑,我们要先了解有这种使用方式,在看源码才会清晰

先记住 ConstructorArgumentValues 类,后面源码会看到



private final Map<Integer, ValueHolder> indexedArgumentValues = new LinkedHashMap<>();// 保存

private final List<ValueHolder> genericArgumentValues = new ArrayList<>();// 保存
    
public void addGenericArgumentValue(Object value) {
    this.genericArgumentValues.add(new ValueHolder(value));
}

public void addIndexedArgumentValue(int index, @Nullable Object value) {
    addIndexedArgumentValue(index, new ValueHolder(value));
}

public void addIndexedArgumentValue(int index, ValueHolder newValue) {
    Assert.isTrue(index >= 0, "Index must not be negative");
    addOrMergeIndexedArgumentValue(index, newValue);
}

private void addOrMergeIndexedArgumentValue(Integer key, ValueHolder newValue) {
    ValueHolder currentValue = this.indexedArgumentValues.get(key);
    if (currentValue != null && newValue.getValue() instanceof Mergeable) {
        Mergeable mergeable = (Mergeable) newValue.getValue();
        if (mergeable.isMergeEnabled()) {
            newValue.setValue(mergeable.merge(currentValue.getValue()));
        }
    }
    this.indexedArgumentValues.put(key, newValue);
}

指定构造参数的代码如上,就是保存到了indexedArgumentValues和genericArgumentValues,后面实例化Bean的时候就会用到,实例化Bean的源码后面文章分析


欢迎关注,学习不迷路!


http://www.kler.cn/news/133839.html

相关文章:

  • Prometheus+Grafana监控
  • 【Java并发编程七】Java内存模型
  • Django command执行脚本
  • C++初阶 日期类的实现(上)
  • 专业数据标注公司:景联文科技领航数据标注行业,满足大模型时代新需求
  • ⑩④【MySQL】什么是视图?怎么用?视图的检查选项? 视图的作用?[VIEW]
  • 【Redis】RedisTemplate最全的常用方法
  • VB.net webbrowser 自定义下载接口实现
  • 【数据结构】图的存储结构及实现(邻接表和十字链表)
  • 适用于 Windows 的 10 个最佳视频转换器:快速转换高清视频
  • C++ 字符串的 拼接,插入,查找与截取。
  • 消息消费过程
  • CnosDB有主复制演进历程
  • main.js 中的 render函数
  • 几种典型的深度学习算法:(CNN、RNN、GANS、RL)
  • S32K324 UDS Bootloader开发-下位机篇-Bootload软件(2)
  • Redis:新的3种数据类型Bitmaps、HyperLoglog、Geographic
  • SELinux零知识学习十七、SELinux策略语言之类型强制(2)
  • 日志维护库:loguru
  • 图论| 827. 最大人工岛 127. 单词接龙
  • 运行ps显示msvcp140.dll丢失怎么恢复?msvcp140.dll快速解决的4个不同方法
  • react antd下拉选择框选项内容换行
  • js:react使用zustand实现状态管理
  • Shaderlab的组成部分SubShader
  • 分类预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多特征分类预测
  • C#中.NET 6.0 控制台应用通过EF访问新建数据库
  • 夺走的第一份工作竟是OpenAI CEO?
  • Linux文件和文件夹命令详解
  • MIB 6.1810实验Xv6 and Unix utilities(2)sleep
  • 九、Linux用户管理