手写spring 实现ioc di ,以及了解aop实现原理,看完理解更上一层楼

spring ioc的实现原理:

ioc就是实现控制反转,把对象的创建交给spring容器进行管理,然后我们在用的时候就不用每次去创建新的对象了,直接从spring容器里面拿就行了。

那么是如何实现的?

首先我们spring在启动的时候会去获取我们类上面有ComponentScan注解的类,然后去解析这个注解的值。然后我们就可以得到扫描包的路径了。

然后拿到这个路径之后我们对这个路径下面的包进行扫描,获取包下面的所有文件名,去通过字符串截取获取包的类名。然后通过类名进行反射获取到这个类的对象,然后再判断这个类是否有component注解,然后再通过注解判断是不是单例,如果是单例bean,我们就把这个类的类名作为键,值的话BeanDefintion作为值。BeanDefintion里面放的是类class和是否是单例。然后把放到beanDefinitionMap里面去。

ini 复制代码
try {  Class<?> aClass = classLoader.loadClass(name);
     //判断有没有注解
     Component component = aClass.getDeclaredAnnotation(Component.class);
     Aspect aspect = aClass.getDeclaredAnnotation(Aspect.class);
     String typeName = aClass.getName().substring(aClass.getName().lastIndexOf(".")+1);
     BeanDefinition beanDefinition=new BeanDefinition();
     //如果是切面就直接放进集合
     if (aspect!=null){
         boolean add = aspectList.add(aClass.getDeclaredConstructor().newInstance());

     }

     if (component != null) {

         Scope scope = aClass.getDeclaredAnnotation(Scope.class);
         beanDefinition.setaClass(aClass);


         //判断当前类有实现这个beanPostPro接口
         if (BeanPostProcessor.class.isAssignableFrom(aClass)){
             BeanDefinition beanDefinition1=new BeanDefinition();
             beanDefinition1.setaClass(aClass);
             beanDefinition1.setScope("singleton");

             beanDefinitonMap.put(typeName,beanDefinition1);
             //                            BeanPostProcessor bean = (BeanPostProcessor)aClass.getDeclaredConstructor().newInstance();
             BeanPostProcessor bean = (BeanPostProcessor)getBean(typeName);
             //                            BeanDefinition beanDefinition2=new BeanDefinition();
             beanPostProcessorList.add(bean);

             //                            beanDefinition2.setaClass(aClass);
             //                            beanDefinitonMap.put(typeName,beanDefinition);
         }

         if (scope!=null){
             String name2 = scope.value();
             beanDefinition.setScope(name2);
         }else {
             beanDefinition.setScope("singleton");
         }
         String value= component.value();
         if (value.equals("")){
             //把bean传进map集合
             beanDefinitonMap.put(UpdateClassName.lowName(typeName),beanDefinition);
         }else {

             //把bean传进map集合
             beanDefinitonMap.put(component.value(),beanDefinition);
         }

     }

然后扫描之后我们会对beanDefinitionMap进行遍历获取每一个键的值,判断是不是单例,如果是单例我们就调用creatBean的方法去得到一个bean,放到我们的单例池map里面去

DI原理

creatBean方法:传入类名,beanDefinition 返回一个类

我们首先会去通过beanDefinition获取类,然后通过反射无参构造方法创建类对象,然后我们会

遍历这个类所有字段的注解,如果有什么autowired的注解,我们会去调用getBean方法去获取一个bean,然后通过反射把对象设置到这个类里面去。

这就是autowire的原理,也是我们di的原理。

aop原理

然后我们一半还会在创建的时候进行初始化操作

在初始化操作之前我们获取遍历beanPostProcessorList集合里面bean,(这里面的bean也是通过扫描的时候判断是是否实现beanPostProssor这个接口,然后实现了就通过getbean方法获取bean,把bean放到我们的beanPostProcessorList里面去。)然后调用里面的前置通知方法,在前置通知方法里面我们会去传入一个对象和类名,我们通过动态代理去截取这个类

这样我们就可以在类执行之前对这个类做什么事情了。然后接着初始化,接着就是后置通知。

这就是aop的实现原理。

getBean方法:

简而言之就是先判断是不是单例,如果是我们就从之前扫描的时候创建的单例Map里拿,不是的话就直接调用creatBean方法。

gitee地址:gitee.com/yao-genghan...

技术交流qq:791842566

相关推荐
Miraitowa_cheems16 小时前
LeetCode算法日记 - Day 88: 环绕字符串中唯一的子字符串
java·数据结构·算法·leetcode·深度优先·动态规划
黑云压城After16 小时前
vue2实现图片自定义裁剪功能(uniapp)
java·前端·javascript
zcl_199118 小时前
记一次ThreadLocal导致的生产事故
java
RoboWizard18 小时前
怎么判断我的电脑是否支持PCIe 5.0 SSD?Kingston FURY Renegade G5
java·spring·智能手机·电脑·金士顿
毕设源码-钟学长18 小时前
【开题答辩全过程】以 儿童游泳预约系统为例,包含答辩的问题和答案
java·eclipse
皮皮林55119 小时前
5种接口频率监控方案实战对比,性能、成本、复杂度全解析!
java
似水流年 光阴已逝19 小时前
从Jar包到K8s上线:全流程拆解+高可用实战
java·kubernetes·jar
YA33319 小时前
java设计模式八、组合模式
java·设计模式·组合模式
一枚码仔20 小时前
SpringBoot启动时执行自定义内容的5种方法
java·spring boot·后端
桦说编程20 小时前
如何在Java中实现支持随机访问的固定窗口队列
java·数据结构·后端