基于注解方式纯手写spring-ioc

1.定义注解


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExtService {

}

2.工具类

https://blog.csdn.net/qq_41988225/article/details/84393804

3.主要功能类

package com.wangyu.extspring.annotation;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.StringUtils;

/**
 * 手写ioc注解版本 
 *
 */

public class ExtClassPathXmlApplicationContext {

    //扫包范围
    private String                                   packageName;
    //存储加了注解的类
    private static ConcurrentHashMap<String, Object> beansMap = null;

    public ExtClassPathXmlApplicationContext(String packageName) throws Exception {
        beansMap = new ConcurrentHashMap<String, Object>();
        if (StringUtils.isEmpty(packageName)) {
            return;
        }
        this.packageName = packageName;
        initBeans();
        initEntryField();
    }

    //给容器中的对象的初始化属性
    public void initEntryField() throws Exception {
        //遍历所有的bean容器对象,判断是否加了extresource注解
        for (Entry<String, Object> entry : beansMap.entrySet()) {
            String key = entry.getKey();
            Object object = entry.getValue();
            attrAssion(object);
        }

    }

    //获取bean
    public Object getBean(String beanId) throws Exception {
        if (StringUtils.isEmpty(beanId)) {
            throw new Exception("该beanid是空的");
        }
        //从spring容器获取bean
        Object object = beansMap.get(beanId);
        /**if (object == null) {
            throw new Exception("class not found ");
        }*/
        //3.使用反射机制进行初始化
        return object;
    }

    //初始化对象
    public void initBeans() throws Exception {
        //1.使用java反射机制,获取当前包下的所有类
        List<Class<?>> classes = ClassUtil.getClasses(packageName);
        //2.判断类上面是否有注解
        ConcurrentHashMap<String, Object> classExisAnnotation = findClassExisAnnotation(classes);
        if (classExisAnnotation == null) {
            throw new Exception("该包的类没有加注解");
        }

    }

    public ConcurrentHashMap<String, Object> findClassExisAnnotation(List<Class<?>> classes) throws ClassNotFoundException, InstantiationException,
                                                                                            IllegalAccessException {
        for (Class<?> classInfo : classes) {
            ExtService annotation = classInfo.getAnnotation(ExtService.class);
            if (annotation != null) {
                //类名小写作为beanId
                String className = classInfo.getSimpleName();
                String beanId = toLowerCaseFirstOne(className);
                Object newInatance = newInatance(classInfo);
                beansMap.put(beanId, newInatance);
                continue;
            }
        }
        return beansMap;
    }

    // 首字母转小写
    public static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
    }

    //创建对象
    public Object newInatance(Class<?> classInfo) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        return classInfo.newInstance();
    }

    //依赖注入原理分析
    public void attrAssion(Object object) throws Exception {
        Class<? extends Object> classInfo = object.getClass();
        //获取属性
        Field[] declaredFields = ((Class<?>) classInfo).getDeclaredFields();
        for (Field field : declaredFields) {
            ExtResource annotation = field.getAnnotation(ExtResource.class);
            if (annotation != null) {
                //获取属性名称
                String beanId = field.getName();
                Object bean = getBean(beanId);
                if (bean != null) {
                    //默认使用属性名称,查找容器对象(当前对象,给属性赋值 )
                    field.setAccessible(true);
                    //给容器中的对象的属性进行赋值
                    field.set(object, bean);
                }
            }
        }

    }
}

4.测试

public class ExtTest {
    public static void main(String[] args) throws Exception {
        ExtClassPathXmlApplicationContext ext = 
                new ExtClassPathXmlApplicationContext("com.wangyu.extspring.annotation.service");
        UserService bean = (UserService) ext.getBean("userService5");
        System.out.println(bean);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41988225/article/details/84393940