Spring学习——模拟Spring Ioc注解版

Spring学习——模拟Spring Ioc注解版

自己模拟的Spring Ioc注解版,加深对Spring底层的了解。这里只支持使用@Autowired注解通过类型进行自动装配。

自定义@Component

用来给容器中添加组件

package com.hrious.core.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 将组件添加到容器中
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
    String value() default "";
}

自定义@Autowired

package com.hrious.core.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 通过类型进行自动注入
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}

容器 AnnotaionConfigIocContainer

import com.hrious.core.anno.Autowired;
import com.hrious.core.anno.Component;

import java.io.File;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 这里只支持使用@Component向容器中添加组件,和使用@Autowired自动装配
 */
public class AnnotaionConfigIocContainer {
    // 系统文件分隔符
    private static final String SEPARATOR = File.separator;
    // 保存扫描出来的类的Class对象
    private Map<String, Class> classMap = new HashMap<>();
    // 保存首先实例化对象
    private Map<String, Object> temporaryMap = new HashMap<>();
    // 保存依赖添加完成后的对象
    private Map<String, Object> objectMap = new HashMap<>();

    // 提供唯一的构造方法
    public AnnotaionConfigIocContainer(String scanPackage) {
        // 扫描
        this.scan(scanPackage);
        // 填充相关依赖
        injectDepends();
    }

    public <T> T getBean(Class<T> clazz) {
        T bean = null;
        int count = 0;
        for (Map.Entry<String, Class> entry : classMap.entrySet()) {
            Class value = entry.getValue();
            if (clazz.isAssignableFrom(value)) {
                bean = (T) objectMap.get(entry.getKey());
                count++;
            }
        }
        if (null == bean) {
            throw new RuntimeException("没有类型为:" + clazz.getName() + "的bean");
        }
        if (count == 1) {
            return bean;
        } else {
            // 通过类型获取的bean可能会有多个
            throw new RuntimeException("需要一个" + clazz.getName() + "类型的bean,找到了" + count + "个");
        }
    }

    public Object getBean(String beanName) {
        Object bean = objectMap.get(beanName);
        if (null == bean) {
            throw new RuntimeException("没有名字为:" + beanName + "的bean");
        }
        return bean;
    }

    // 注入相关依赖
    private void injectDepends() {
        // 查找每个类中的依赖
        for (Map.Entry<String, Class> entry : classMap.entrySet()) {
            Class clazz = entry.getValue();
            String beanName = entry.getKey();
            // 获取所有属性
            Field[] fields = clazz.getDeclaredFields();
            // 从容器中获取需要注入属性的对象
            Object bean = temporaryMap.get(beanName);
            for (Field field : fields) {
                // 判断是否存在@Autowired
                if (field.isAnnotationPresent(Autowired.class)) {
                    // 需要判断依赖个数
                    Class needType = field.getType();
                    Object needBean = null;
                    int count = 0;
                    // 寻找依赖
                    for (Map.Entry<String, Class> entry2 : classMap.entrySet()) {
                        Class tempType = entry2.getValue();
                        // 比较是否为同一个类型
                        if (tempType == needType) {
                            count++;
                            needBean = temporaryMap.get(entry2.getKey());
                        } else {
                            // 满足注入条件
                            if (needType.isAssignableFrom(tempType)) {
                                count++;
                                needBean = temporaryMap.get(entry2.getKey());
                            }
                        }
                    }
                    if (count == 1) {
                        field.setAccessible(true);
                        try {
                            field.set(bean, needBean);
                        } catch (IllegalAccessException e) {
                        }
                    } else {
                        throw new RuntimeException(clazz.getName() + "需要一个的bean" + needType.getName() + "类型,找到了" + count + "个");
                    }
                }
            }
            // 将标注有@Component注解的类添加到objectMap中
            objectMap.put(beanName, bean);
        }
    }

    // 扫描
    private void scan(String basePackage) {
        // 当前项目的classpath
        String basePath = AnnotaionConfigIocContainer.class.getResource("/").getPath();
        // 扫描的包路径
        String scanPachagePath = new String(basePackage);
        scanPachagePath = basePath + scanPachagePath.replaceAll("\\.", "\\" + SEPARATOR);
        File file = new File(scanPachagePath);
        String[] scanFiles = file.list();
        for (String scanFile : scanFiles) {
            if (scanFile.contains(".class")) {
                String className = scanFile.replace(".class", "");
                if (!this.getClass().getSimpleName().equals(className)) {
                    String qualifyClassName = basePackage + "." + className;
                    try {
                        Class<?> clazz = Class.forName(qualifyClassName);
                        // 判断是否有@Component注解
                        if (clazz.isAnnotationPresent(Component.class)) {
                            // 判断是否自定义名称
                            Component component = clazz.getAnnotation(Component.class);
                            String value = component.value();
                            String beanName = null;
                            if ("".equals(value)) {
                                // 没有指定名称
                                // 需要转换名称
                                beanName = tranformBeanName(className);
                            } else {
                                // 指定了name
                                beanName = value;
                            }
                            // 容器中beanName唯一
                            // 判断beanName是否存在
                            if (classMap.containsKey(beanName)) {
                                throw new RuntimeException("名称为:" + beanName + "的bean已经存在");
                            } else {
                                temporaryMap.put(beanName, clazz.newInstance());
                                classMap.put(beanName, clazz);
                            }
                        }
                    } catch (ClassNotFoundException e) {
                    } catch (IllegalAccessException | InstantiationException e) {
                        // 构造方法私有化或者是抽象类和接口
                        throw new RuntimeException("无法创建" + qualifyClassName + "对象");
                    }
                }
            } else {
                scan(basePackage + "." + scanFile);
            }
        }
    }

    // 转换beanName满足首字母小写的驼峰原则
    private String tranformBeanName(String beanName) {
        if (beanName.length() == 1) {
            return beanName.toLowerCase();
        } else {
            return beanName.substring(0, 1).toLowerCase() + beanName.substring(1);
        }
    }
}

你可能感兴趣的:(Java)