当前位置: 首页 > 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/a/133839.html

相关文章:

  • c++写一个死锁并且自己解锁
  • SpringBoot参数注解
  • 从社交媒体到元宇宙:Facebook未来发展新方向
  • 【专题】计算机网络之网络层
  • MYSQL 库,表 基本操作
  • Linux设置socks代理
  • 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. 单词接龙