承接上一章,如何获取自定义注解标记的类
已经获取到所有自定义注解标记的类,并且把它们都放入了一个Map<Class<?>, Object>(类和各自实例的映射)中。
那么如何来实现依赖注入呢?
@Controller
public class HelloController{
@Inject //自定义的依赖注入 注解
private HelloService helloService;
// .....
}
思路:利用反射获得该类的所有成员变量,遍历找出依赖注入注解标记的变量(是一个类),调用Field的set方法,将该变量的实例注入到需要注入的类的实例里面
//假设beanMap记录了所有的Bean和各自实例的映射关系
if (CollectionUtil.isNotEmpty(beanMap)) { //benaMap 类型是Map<Class<?>, Object>
// 遍历Bean Map
for(Map.Entry<Class<?>, Object> beanEntry: beanMap.entrySet()){
//从BeanMap中获取Bean类与Bean实例
Class<?> beanClass = beanEntry.getKey();
Object beanInstance = beanEntry.getValue();
//获取Bean类定义的所有成员变量
Field[] beanFields = beanClass.getDeclaredFields();
if(ArrayUtils.isNotEmpty(beanFields)){
for(Field beanField: beanFields){
//判断当前Bean Field是否带有Inject注解
if(beanField.isAnnotationPresent(Inject.class)){
//在Bean Map中获取Bean Field对应的实例
Class<?> beanFieldClass = beanField.getType();
Object beanFieldInstance = beanMap.get(beanFieldClass);
if(beanFieldInstance != null){
//通过反射初始化BeanField的值
ReflectionUtil.setField(beanInstance, beanField, beanFieldInstance);
}
}
}
}
}
}
//ReflectionUtil的setField方法
public static void setField(Object obj, Field field, Object value){
try {
field.setAccessible(true);
field.set(obj, value);
} catch (Exception e) {
logger.error("set field failure", e);
throw new RuntimeException(e);
}
}