手写高仿真Spring框架-依赖注入DI

7 篇文章 0 订阅

手写高仿真Spring框架

流行词:顶层设计 依赖注入

参考代码:https://gitee.com/li-lixiang/lean-spring-2.0.git

在上衣篇blog中,已经实现Spring IOC容器的初始化,接下来对伪容器(真正的容器时保存BeanWrapper对象的)中的类名,进行实例注入(非延时加载)。也就是完成依赖注入。

依赖注入

  1. 初始化(实例化)
    • 通过读取伪容器中的BeanDefinition对象,获取类信息,从而通过反射机制进行实例化对象。
    • 而Spring的做法非此直接,而是用到BeanWrapper对象进行一次包装。再将BeanWrapper对象存到真的IOC容器中。
  2. 注入(单例,多例的处理,相互依赖的情况处理BeanWrapper包装器模式处理)

初始化

  1. 拿到需要实例化的对象
  2. 反射实例化,得到一个对象
  3. 将实例化对象通过BeanWrapper封装
  4. 将封装的BeanWrapper对象,缓存到factoryBeanObjectCache
    private Object instantiateBean(String beanName, GPBeanDefinition gpBeanDefinition) {
        //1、拿到要实例化的对象的类名
        String className = gpBeanDefinition.getBeanClassName();

        //2、反射实例化,得到一个对象
        Object instance = null;
        try {
//            gpBeanDefinition.getFactoryBeanName()
            //假设默认就是单例,细节暂且不考虑,先把主线拉通
            if(this.factoryBeanObjectCache.containsKey(className)){
                instance = this.factoryBeanObjectCache.get(className);
            }else {
                Class<?> clazz = Class.forName(className);
                instance = clazz.newInstance();

                GPAdvisedSupport config = instantionAopConfig(gpBeanDefinition);
                config.setTargetClass(clazz);
                config.setTarget(instance);

                //符合PointCut的规则的话,闯将代理对象
                if(config.pointCutMatch()) {
                    instance = createProxy(config).getProxy();
                }

                this.factoryBeanObjectCache.put(className,instance);
                this.factoryBeanObjectCache.put(gpBeanDefinition.getFactoryBeanName(),instance);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return instance;
    }

注入

  1. 判断只有加了注解的类,才执行依赖注入
  2. 获得所有的fields,然后对其处理,对所有需要依赖注入的fields,也就是将factoryBeanObjectCache中获取实例化的对象进行注入
    private void populateBean(String beanName, GPBeanDefinition gpBeanDefinition, GPBeanWrapper gpBeanWrapper) {
        Object instance = gpBeanWrapper.getWrappedInstance();

//        gpBeanDefinition.getBeanClassName();

        Class<?> clazz = gpBeanWrapper.getWrappedClass();
        //判断只有加了注解的类,才执行依赖注入
        if(!(clazz.isAnnotationPresent(GPController.class) || clazz.isAnnotationPresent(GPService.class))){
            return;
        }

        //获得所有的fields
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if(!field.isAnnotationPresent(GPAutowired.class)){ continue;}

            GPAutowired autowired = field.getAnnotation(GPAutowired.class);

            String autowiredBeanName =  autowired.value().trim();
            if("".equals(autowiredBeanName)){
                autowiredBeanName = field.getType().getName();
            }

            //强制访问
            field.setAccessible(true);

            try {
                //为什么会为NULL,先留个坑
                if(this.factoryBeanInstanceCache.get(autowiredBeanName) == null){ continue; }
//                if(instance == null){
//                    continue;
//                }
                field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName).getWrappedInstance());
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值