我们在Controller中定义了Service成员变量,然后在Controller的Action方法中调用Service成员变量的方法,那么如果实现Service的成员变量? 之前定义了@Inject注解,就用它来实现Service是例话,那么谁来实例化呢。
不是开发者通过new的方式来实例化,而是通过框架自身来实例化,像这类实例化过程称为IOC(控制反转),控制不是由开发者来决定,而是反转给框架了。一般也将控制反转称为DI(依赖注入),可以理解为将某个类需要依赖的成员注入到这个类中,那么我们该如何实现了?
最简单的方式是,先通过BeanHelper获取所有的BeanMap(是一个Map<Class<?>,Object>结构,记录了类与对象的映射关系),然后遍历这个映射关系,分别取出Bean类与Bean实例,进而通过反射获取类中所有成员变量。继续遍历这些成员变量,在循环中判断这些成员变量是否带有Inject注解,若带有该注解,则从BeanMap根据Bean类取出Bean实例。最后通过ReflectionUtil的setField的方法来修改当前成员变量的值。
把上面的逻辑写成一个IocHelper的类,让它来完成这件事,代码如下:
1 package org.smart4j.framework.helper; 2 3 4 import org.smart4j.framework.annotation.Inject; 5 import org.smart4j.framework.org.smart4j.framework.util.ArrayUtil; 6 import org.smart4j.framework.org.smart4j.framework.util.CollectionUtil; 7 import org.smart4j.framework.org.smart4j.framework.util.ReflectionUtil; 8 9 import java.lang.reflect.Field; 10 import java.util.Map; 11 12 /** 13 * Created by jack on 2017/5/23. 14 * 依赖注入助手类 15 */ 16 public class IocHelper { 17 static { 18 //获取所有的Bean类与Bean实例之间的关系(简称Bean Map) 19 Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap(); 20 if (CollectionUtil.isNotEmpty(beanMap)) { 21 //遍历beanMap 22 for (Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) { 23 //从beanMap中获取bean类与bean实例 24 Class<?> beanClass = beanEntry.getKey(); 25 Object beanInstance = beanEntry.getValue(); 26 //获取Bean类定义的所有成员变量(简称Bean Field) 27 Field [] beanFields = beanClass.getDeclaredFields(); 28 if (ArrayUtil.isNotEmpty(beanFields)){ 29 //遍历beanField 30 for (Field beanField : beanFields) { 31 //判断当前的Bean Field是否带有Inject注解 32 if (beanField.isAnnotationPresent(Inject.class)){ 33 //在Bean Map中获取Bean Field对应的实例 34 Class<?> beanFieldClass = beanField.getType(); 35 Object beanFieldInstance = beanMap.get(beanFieldClass); 36 if (beanFieldInstance != null){ 37 //通过放射初始化beanField值 38 ReflectionUtil.setField(beanInstance,beanField,beanFieldInstance); 39 } 40 } 41 } 42 } 43 44 45 } 46 } 47 } 48 }