要想实现依赖注入,首先我们需要在BeanDefined中定义属性的键值对:
//存放属性键值对
private Map<String, String> propertyMap = new HashMap<>(16);
在BeanFactory中返回实例化对象前,给对象赋值。
实现setvalue方法:
private void setValue(Object instance, Class beanField, Map<String, String> propertyMap) throws Exception {
//获取所有的方法
Method[] methods = beanField.getDeclaredMethods();
//对properMap进行解析,获取键值对,也就是需要注入的属性和属性值
Set<String> propertySet = propertyMap.keySet();
Iterator<String> propertyIterator = propertySet.iterator();
while (propertyIterator.hasNext()){
String propertyKey = propertyIterator.next();
String propertyValue = propertyMap.get(propertyKey);
//获取的属性
Field field = beanField.getDeclaredField(propertyKey);
//属性对应的set方法
String methodName = "set" + field.getName();
//对方法进行过滤
for (int i = 0; i < methods.length; i ++){
Method method = methods[i];
if (methodName.equalsIgnoreCase(method.getName())){
//判断set方法的类型 也就是属性的类型
Class fieldType = field.getType();
if (fieldType == String.class){
method.invoke(instance, propertyValue);
} else if (fieldType == Integer.class){
method.invoke(instance, Integer.valueOf(propertyValue));
//这里只对List类型做判断
} else if (fieldType == List.class){
List<String> tmpList = new ArrayList<>(16);
String[] itemArray = propertyValue.split(",");
for (int j = 0; j < itemArray.length; j ++){
tmpList.add(itemArray[i]);
}
}else {
throw new RuntimeException("暂不该支持属性类型注入");
}
}
}
}
}
实现逻辑不难,就是一层一层解析,基本步骤可以看注解。
测试类TestMain
@Test
public void testPropertyMap() throws Exception {
//注册bean
BeanDefined beanObj = new BeanDefined();
beanObj.setBeanId("user");
beanObj.setClassPath("com.lks.bean.User");
//设置propertyMap 类似Spring中依赖注入属性值
Map<String, String> propertyMap = beanObj.getPropertyMap();
propertyMap.put("name", "萧峰");
propertyMap.put("age", "31");
propertyMap.put("sex", "男");
List<BeanDefined> beanDefineds = new ArrayList<>(16);
beanDefineds.add(beanObj);
//声明BeanFactory,类似于Spring中的ApplicationContext
BeanFactory factory = new BeanFactory(beanDefineds);
//实际调用
User user = (User) factory.getPropertyBean("user");
System.out.println(user.toString());
}
该章节内容是在上一章的基础上实现的,主要是为了对 Spring 依赖注入的基本实现有一个了解和掌握,从上面的实例中就可以看出,Spring的依赖注入主要依赖Java的反射机制。
代码地址:https://github.com/kaisongli/spring-demo.git