依赖注入:如何给Bean注入值并解决循环依赖问题?
值的注入
要理清这个问题,我们要先来看看Spring是如何解析
我们以下面的XML配置为基准进行学习。
<?xml version="1.0" encoding="UTF-8" ?>
和上面的配置属性对应,在测试类AServiceImpl中,要有相应的name、level、property1、property2字段来建立映射关系,这些实现体现在构造函数以及settter、getter等方法中。
public class AServiceImpl implements AService {
private String name;
private int level;
private String property1;
private String property2;
public AServiceImpl() {
}
public AServiceImpl(String name, int level) {
this.name = name;
this.level = level;
System.out.println(this.name + "," + this.level);
}
public void sayHello() {
System.out.println(this.property1 + "," + this.property2);
}
// 在此省略property1和property2的setter、getter方法
}
接着,简化ArgumentValues类,移除暂时未用到的方法。
public class ArgumentValues {
private final List
public ArgumentValues() {
}
public void addArgumentValue(ArgumentValue argumentValue) {
this.argumentValueList.add(argumentValue);
}
public ArgumentValue getIndexedArgumentValue(int index) {
ArgumentValue argumentValue = this.argumentValueList.get(index);
return argumentValue;
}
public int getArgumentCount() {
return (this.argumentValueList.size());
}
public boolean isEmpty() {
return (this.argumentValueList.isEmpty());
}
}
做完准备工作之后,我们重点来看核心工作:解析
public void loadBeanDefinitions(Resource resource) {
while (resource.hasNext()) {
Element element = (Element) resource.next();
String beanID = element.attributeValue("id");
String beanClassName = element.attributeValue("class");
BeanDefinition beanDefinition = new BeanDefinition(beanID,
beanClassName);
//处理属性
List
PropertyValues PVS = new PropertyValues();
for (Element e : propertyElements) {
String pType = e.attributeValue("type");
String pName = e.attributeValue("name");
String pValue = e.attributeValue("value");
PVS.addPropertyValue(new PropertyValue(pType, pName, pValue));
}
beanDefinition.setPropertyValues(PVS);
//处理构造器参数
List<Element> constructorElements = element.elements("constructor-
arg");
ArgumentValues AVS = new ArgumentValues();
for (Element e : constructorElements) {
String aType = e.attributeValue("type");
String aName = e.attributeValue("name");
String aValue = e.attributeValue("value");
AVS.addArgumentValue(new ArgumentValue(aType, aName, aValue));
}
beanDefinition.setConstructorArgumentValues(AVS);
this.simpleBeanFactory.registerBeanDefinition(beanID,
beanDefinition);
}
}
}
从上述代码可以看出,程序在加载Bean的定义时要获取
那么,将这些配置的值读取进内存之后,我们怎么把它作为Bean的属性注入进去呢?这要求我们在创建Bean的时候就要做相应的处理,给属性赋值。针对XML配置的Value值,我们要按照数据类型分别将它们解析为字符串、整型、浮点型等基本类型。在SimpleBeanFactory类中,调整核心的createBean方法,我们修改一下。
private Object createBean(BeanDefinition beanDefinition) {
Class<?> clz = null;
Object obj = null;
Constructor<?> con = null;
try {
clz = Class.forName(beanDefinition.getClassName());
// 处理构造器参数
ArgumentValues argumentValues =
beanDefinition.getConstructorArgumentValues();
//如果有参数
if (!argumentValues.isEmpty()) {
Class<?>[] paramTypes = new Class<?>
[argumentValues.getArgumentCount()];
Object[] paramValues = new
Object
<< 上一篇
下一篇 >>