细说之前博客--手写简单IOC

什么是IOC

个人感觉ioc就是一个容器嘛,说白也就是个map,spring用的只是线程安全的map罢了。这个map放的是自己注入的对象,这些对象也被称为bean对象。写一个ioc不也就是搞一个map然后把对象放进来,然后自己可以去get,这就是ioc的本质呀!

IOC的一些对象

  • BeanDefinition :放置对象的信息,比如:class,scope等等
  • BeanFactory : bean工厂对象,里面有实列池,就是map
  • BeanPostProcessor : bean的后置处理器,在初始化之前和之后都可以进行处理
  • InitializingBean : 初始化接口

IOC实例化的流程

  1. 遍历所有的class,将其解析成BeanDefinition对象
  2. 实例化对象,就是new 一个无参的
  3. 给对象属性赋值
  4. 初始化接口
  5. 后置处理器
  6. 放入map

这是我自己实现的步骤,spring的具体步骤和顺序大家可以自行百度

实现逻辑

  1. 遍历所有的class,将其解析成BeanDefinition对象:
/**
     * 解析对象成beanDefinition
     *
     * @param allClass
     */
    public void initBeanDefinitions(List<Class<?>> allClass) {
        allClass.forEach((item) -> {
            if (item.isAnnotationPresent(Configuration.class)) {
                beanFactoryUtil.setBeanDefinition(item);
                Method[] declaredMethods = item.getDeclaredMethods();
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(Bean.class)) {
                        Parameter[] parameters = declaredMethod.getParameters();
                        Bean annotation = declaredMethod.getDeclaredAnnotation(Bean.class);
                        Class returnType = declaredMethod.getReturnType();
                        if (returnType.getName().equals("void")) {

                        } else {
                            Object invoke = null;
                            try {
                                invoke = declaredMethod.invoke(item.newInstance(), parameters);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            } catch (InstantiationException e) {
                                e.printStackTrace();
                            }
                            if (annotation.value().equals("")) {
                                beanFactoryUtil.setSingletonObject(declaredMethod.getName(), invoke);
                            } else {
                                beanFactoryUtil.setSingletonObject(annotation.value(), invoke);
                            }
                        }

                    }
                }
            }
            if (item.isAnnotationPresent(Component.class)) {
                Component declaredAnnotation = item.getDeclaredAnnotation(Component.class);
                if (declaredAnnotation.value().equals("")) {
                    beanFactoryUtil.setBeanDefinition(item);
                } else {
                    beanFactoryUtil.setBeanDefinition(item, declaredAnnotation.value());
                }
            }
            if (item.isAnnotationPresent(Controller.class)) {
                Controller declaredAnnotation = item.getDeclaredAnnotation(Controller.class);
                if (declaredAnnotation.value().equals("")) {
                    beanFactoryUtil.setBeanDefinition(item);
                } else {
                    beanFactoryUtil.setBeanDefinition(item, declaredAnnotation.value());
                }
            }
        });
    }

	public void setBeanDefinition(Class clazz) {
        BeanDefinition beanDefinition = new BeanDefinition();
        beanDefinition.setClazz(clazz);
        beanDefinition.setBeanName(clazz.getSimpleName());
        if (clazz.isAnnotationPresent(Scope.class)) {
            Scope declaredAnnotation = (Scope) clazz.getDeclaredAnnotation(Scope.class);
            if (declaredAnnotation.value().equals("")) {
                beanDefinition.setScope("singleton");
            } else {
                beanDefinition.setScope(declaredAnnotation.value());
            }
        } else {
            beanDefinition.setScope("singleton");
        }
        if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
            beanDefinition.setBeanPostProcessor(true);
        } else {
            beanDefinition.setBeanPostProcessor(false);
        }
        if (DateHandle.class.isAssignableFrom(clazz)) {
            beanDefinition.setDateHandle(true);
        } else {
            beanDefinition.setDateHandle(false);
        }
        if (WebMvcConfigurer.class.isAssignableFrom(clazz)) {
            beanDefinition.setWebMvcConfigurer(true);
        } else {
            beanDefinition.setWebMvcConfigurer(false);
        }
        if(clazz.isAnnotationPresent(Aspect.class)){
            beanDefinition.setAspect(true);
        }else {
            beanDefinition.setAspect(false);
        }
        if(clazz.isAnnotationPresent(Controller.class)){
            beanDefinition.setController(true);
        }else {
            beanDefinition.setController(false);
        }
        beanFactory.setBeanDefinition(beanDefinition);


    }
  1. clazz.newInstance();
  2. 属性赋值,我只定义了一个注解
public void autowiredHandle(Object newInstance, Field declaredField,
                                ConcurrentHashMap<String, Object> originalObjects,
                                ConcurrentHashMap<String, Object> singletonObjects
    ) throws IllegalAccessException, InstantiationException, ClassNotFoundException {

        if (declaredField.getModifiers() == 2 || declaredField.getModifiers() == 10
                || declaredField.getModifiers() == 26 || declaredField.getModifiers() == 18) {
            declaredField.setAccessible(true);
        }
        if (declaredField.isAnnotationPresent(Autowired.class)) {
            ArrayList<Object> objects = new ArrayList<>();
            singletonObjects.forEach((key, value) -> {
                if (declaredField.getType().isAssignableFrom(value.getClass())) {
                    objects.add(value);
                }
            });
            if (objects.size() == 0) {
                List<BeanDefinition> beanDefinitions1 = beanFactoryUtil.getBeanDefinition(declaredField.getType());
                if (beanDefinitions1.size() == 0) {

                } else {
                    if (beanDefinitions1.size() == 1) {
                        Object bean = getBean(beanDefinitions1.get(0), originalObjects, singletonObjects);
                        declaredField.set(newInstance, bean);
                    } else {
                        for (BeanDefinition definition : beanDefinitions1) {
                            if (declaredField.getName().equals(definition.getBeanName())) {
                                Object bean = getBean(definition, originalObjects, singletonObjects);
                                declaredField.set(newInstance, bean);
                            }
                        }
                    }
                }
            } else {
                if (objects.size() == 1) {
                    try {
                        declaredField.set(newInstance, objects.get(0));
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    singletonObjects.forEach((key, value) -> {
                        if (key.equals(declaredField.getName())) {
                            try {
                                declaredField.set(newInstance, value);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }

                    });
                }
            }

        }

    }


4.初始化接口这个就是你bean对象如果实现了这个接口,属性赋值完之后就调用这个接口的方法,就这样而已

if (finalNewInstance1 instanceof InitializingBean) {//初始化
          InitializingBean initializingBean = (InitializingBean) finalNewInstance1;
          initializingBean.afterPropertiesSet();
      }
  1. 后置处理器跟初始话一样的,2个方法,初始化之前,初始化之后
beanPostProcessorOrders.forEach((beanPostProcessorOrder -> {//bean前置处理器--初始化之前
            beanPostProcessorOrder.getBeanPostProcessor().postProcessBeforeInitialization(finalNewInstance1, beanDefinition.getBeanName());
        }));
        if (finalNewInstance1 instanceof InitializingBean) {//初始化
            InitializingBean initializingBean = (InitializingBean) finalNewInstance1;
            initializingBean.afterPropertiesSet();
        }
        beanPostProcessorOrders.forEach((beanPostProcessorOrder -> {//bean后置处理器--初始化之后
            beanPostProcessorOrder.getBeanPostProcessor().postProcessAfterInitialization(finalNewInstance1, beanDefinition.getBeanName());
        }));
  1. 放入map就很简单了,,我就不搞代码了,对了有个单例,多例的注解,记得去判断一下,有的就直接从map里面拿,多例就每次创建。还有哈,我这些都在getBean方法里面,用户每次用的时候去实例化,不是一次都实例化好,这样也可以,应该算不同的模式吧,你们可以自己实现一下,搞个啥注解控制。

经典问题

循环依赖: 就是有个A里面有个B属性,B有A属性

正常流程:实例化A , A属性注入时发现B,然后去实例化B,B属性注入时发现A,又去实例化A,这不就死循环了

解决方法:搞一个map出来,充当缓存,每次实例化之后就放入缓存中,那的话先从单例池map拿,没有就去这个缓存map中拿就ok了

这就是二级缓存,2个map。这样可以解决循环依赖问题,不过spring用的三级缓存,原因就是aop,这个大家百度一下,大概就是为了存下aop代理之后的对象,我这边没有用3级缓存,只用了2级。aop功能也实现了,不过可能有bug,可能,嗯~~

总结

这就是我写的ioc主要类容了,本次类容和下次都是去详细讲一下
https://blog.csdn.net/qq_43110503/article/details/119722286?spm=1001.2014.3001.5501
这篇博客的内容
本人今年毕业,说错的地方大家指出别用太暴力的方式,, 球球了。
白天上班,晚上不加班,有精力,有心情的时候 去跟新后面的内容!!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值