1. 实现思路及须要实现的内容

实现思路

  1. 定义相干的注解标签
  2. 实现创立被注解标记的成员变量实例,并将其注入到被@Autowired标记的成员变量中

须要实现的内容

  1. 编写ClassUtil#setField办法为对应的实例设置属性值
  2. 编写@Autowired注解
  3. 编写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...