1. 实现思路及须要实现的内容
实现思路
- 定义相干的注解标签
- 实现创立被注解标记的成员变量实例,并将其注入到被@Autowired标记的成员变量中
须要实现的内容
- 编写ClassUtil#setField办法为对应的实例设置属性值
- 编写@Autowired注解
- 编写DependencyInjector实现属性的依赖注入
2. 第一局部: 编写@Autowired注解和ClassUtil#setField办法
2.1 本局部须要实现的代码如下:
package org.myframework.injection.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * @author wuyiccc * @date 2020/6/13 23:20 * 岂曰无衣,与子同袍~ *//** * Autowired目前只反对成员变量级别的注入 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Autowired { String value() default "";}
/** * 设置类的属性值 * @param field 成员变量 * @param target 类实例 * @param value 成员变量的值 * @param accessible 是否容许设置公有属性 */ public static void setField(Field field, Object target, Object value, boolean accessible) { field.setAccessible(accessible); try { field.set(target, value); } catch (IllegalAccessException e) { log.error("setField error", e); throw new RuntimeException(e); } }
2.2 相干代码解读
3. 第二局部:实现DependencyInjector
3.1 须要实现的代码如下:
package com.wuyiccc.helloframework.injection;import com.wuyiccc.helloframework.core.BeanContainer;import com.wuyiccc.helloframework.injection.annotation.Autowired;import com.wuyiccc.helloframework.util.ClassUtil;import com.wuyiccc.helloframework.util.ValidationUtil;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.Field;import java.util.Set;/** * @author wuyiccc * @date 2020/7/13 14:57 * 岂曰无衣,与子同袍~ */@Slf4jpublic class DependencyInjector { /** * Bean容器 */ private BeanContainer beanContainer; public DependencyInjector() { beanContainer = BeanContainer.getInstance(); } /** * 执行IOC */ public void doIoc() { if (ValidationUtil.isEmpty(beanContainer.getClasses())) { log.warn("empty classes in BeanContainer"); return; } // 遍历容器中的所有class的对象 for (Class<?> clazz : beanContainer.getClasses()) { Field[] fields = clazz.getDeclaredFields(); if (ValidationUtil.isEmpty(fields)) { continue; } for (Field field : fields) { // 找出被Autowired标记的成员变量 if (field.isAnnotationPresent(Autowired.class)) { Autowired autowired = field.getAnnotation(Autowired.class); String autowiredValue = autowired.value(); // value值 // 获取该field的类型 Class<?> fieldClass = field.getType(); // 获取该类型在容器中对应的实例 Object fieldValue = getFieldInstance(fieldClass, autowiredValue); if (fieldValue == null) { throw new RuntimeException("unable to inject relevant type, target fieldClass is:" + fieldClass.getName() + " autowiredValue is : " + autowiredValue); } else { // 通过反射将对应的成员变量实例注入到成员变量所在类的实例里 Object targetBean = beanContainer.getBean(clazz); ClassUtil.setField(field, targetBean, fieldValue, true); } } } } } /** * 依据Class在beanContainer里获取实例或者实现类 * * @param fieldClass 实例中属性的类型 * @param autowiredValue 要注入的值的名称 * @return */ private Object getFieldInstance(Class<?> fieldClass, String autowiredValue) { // 看是否获取同等级的实例 Object fieldValue = beanContainer.getBean(fieldClass); if (fieldValue != null) { return fieldValue; } else { Class<?> implementedClass = geImplementedClass(fieldClass, autowiredValue); if (implementedClass != null) { return beanContainer.getBean(implementedClass); } else { return null; } } } /** * 获取接口i的实现类 * * @param fieldClass 实例中要注入的属性的类型 * @return */ private Class<?> geImplementedClass(Class<?> fieldClass, String autowiredValue) { Set<Class<?>> classSet = beanContainer.getClassesBySuper(fieldClass); if (!ValidationUtil.isEmpty(classSet)) { if (ValidationUtil.isEmpty(autowiredValue)) { if (classSet.size() == 1) { return classSet.iterator().next(); } else { throw new RuntimeException("multiple implemented classes for " + fieldClass.getName() + "please set @Autowired's value to pick one"); } } else { for (Class<?> clazz : classSet) { if (autowiredValue.equals(clazz.getSimpleName())) { return clazz; } } } } return null; }}
3.2 相干代码解说如下:
GitHub地址: https://github.com/wuyiccc/he...