简介
为什么讲这个,是因为在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的源码后面文章分析
欢迎关注,学习不迷路!