自己写一个简单的IOC
什么是SpringIOC?
答:IOC即控制反转,就是我们不在手动的去new一个对象,而是将创建对象的权力交给Spring去管理,我们想要一个User类型的对象,就只需要定义一个User类型的变量user1,然后让Spring去给我们创建对象,然后将创建的对象注入到user1中。
什么是依赖注入?
答:DI机制(DependencyInjection),依赖注入,上面提到的Spring将它创建的对象交给我们创建的变量的过程。依赖注入的方式有三种(set方法注入、构造器注入、注解注入)。下面我们简答的实现注解注入,了解IOC原理。
第一步,创建注解
创建的注解其实没有太大的作用,就是用来标记哪个类需要Spring帮我们去管理,哪个成员变量需要Spring去给我们注入。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*创建注解文件Component.java
*标记需要IOC的类
**/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*创建注解文件Autowired.java
*标记需要Spring帮忙DI的成员变量
**/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
第二部,创建两个需要注解的类
我们想要将MyService和MyController都交给Spring管理(项目启动后将这两个类实例化,然后放入一个HashMap中,等待调用)

import com.xiaoran.springioc.annotation.Component;
@Component
public class MyService {private int id;private String name;private int age;public void speck(String name,int age) {System.out.println("大家好,我叫"+name+"今年"+age+"岁了,请多多关照!");}
}
import com.xiaoran.springioc.annotation.Autowired;
import com.xiaoran.springioc.annotation.Component;
@Component
public class MyController {@Autowiredprivate MyService myService;public void test(){myService.speck("moss",67);}
}
第三步,IOC过程
创建MyIOC类,用于IOC过程
- 在项目启动时,实例化MyIOC,加载MyIOC的无参构造器时,对项目下所有的文件进行扫描,调用实例化方法完成被注释类的实例化和依赖注入。
private String basePath="D:\\Project\\XiaoRanIOC\\src\\main\\java\\com\\xiaoran\\springioc\\"; //项目路径private String basePackage="com.xiaoran.springioc"; //包路径private List<String> filePaths;//所有文件的路径private List<String> beanNames;//所有.java文件的全限定名private Map<String, Object> beans = new HashMap<>();/*** 实例化MyIOC时,让IOC进程伴随无参构造器加载启动*/public MyIOC() throws FileNotFoundException, IllegalAccessException {//扫描路径下所有文件scan();beanNames = new ArrayList<>();initBeanNames();initBeans();}
- 扫描项目下所有文件,将所有文件的路径存入filePaths中
/*** 扫描项目下所有文件,将所有文件的路径存入filePaths中*/public void scan() throws FileNotFoundException {File file = new File(basePath);filePaths=new ArrayList<>();if (file.exists()) {//将file放入列,出队后判断,如果是路径那就继续入队,如果是文件,就将文件路径放入filePaths中Queue<File> queue = new LinkedList<>();queue.add(file);while (!queue.isEmpty()) {File poll = queue.poll();if(poll==null){continue;}if (poll.isDirectory()){File[] files = poll.listFiles();for (File f :files) {queue.add(f);}}else{filePaths.add(poll.getPath());}}}else {throw new FileNotFoundException(basePath + "不存在");}}
- 将所有的.java文件的全限定名放入beanNames中
/***将所有的.java文件的全限定名放入beanNames中*/public void initBeanNames(){for (String string :filePaths) {String replace = string.replace(basePath, "");if (replace.endsWith(".java")) {replace = replace.substring(0, replace.length() - 5);}char[] chars = replace.toCharArray();for (int i = 0; i < chars.length; i++) {if(chars[i]=='\\'){chars[i] = '.';}}beanNames.add(basePackage+"."+new String(chars));}}
- 核心代码:将被@Component注解的类实例化放入beans(HashMap)中,等待调用
/***核心代码:将被@Component注解的类实例化放入beans(HashMap)中,等待调用*/public void initBeans() throws IllegalAccessException {//遍历包路径下所有类,是否被@Component注解,如果被注解就将其实例化放入beansfor (String beanName :beanNames) {try {Class<?> aClass = Class.forName(beanName);//获取类的所有注解Annotation[] declaredAnnotation = aClass.getDeclaredAnnotations();//遍历所有注解,是否是@Component注解for (Annotation annotation :declaredAnnotation) {if (annotation instanceof Component){Object o = aClass.newInstance();beans.put(beanName, o);}}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}}//遍历所有的beans的成员变量,如果有成员变量被@Autowired修饰,就根据成员变量的类型从beans中查找到对应的对象,用此对象给成员变量注入//因为是从beans中查找对象,所以被注入的成员变量对应的类一定是已经被实例化放入beans中的for (Map.Entry<String, Object> entry : beans.entrySet()) {Object value = entry.getValue();Field[] fields = value.getClass().getDeclaredFields();for (Field f :fields) {Annotation[] declaredAnnotations = f.getDeclaredAnnotations();for (Annotation annotation :declaredAnnotations) {if (annotation instanceof Autowired){//获取被@Autowired注解成员变量的类型(全限定名)String typeName = f.getType().getName();Object o = beans.get(typeName);//暴力反射f.setAccessible(true);//将从beans中获得的对象o,注入到该属性上f.set(value,o);}}}}}/*** 对外提供一个方法:根据全限定名返回对象*/public Object getInstance(String beanName){return beans.get(beanName);}
第四步,测试
创建测试类IOCTest
import com.xiaoran.springioc.entity.MyController;
import com.xiaoran.springioc.ioc.MyIOC;
import org.junit.Test;
import java.io.FileNotFoundException;
public class IOCTest {@Testpublic void test() throws FileNotFoundException, IllegalAccessException {MyIOC myIOC = new MyIOC();MyController myController = (MyController)myIOC.getInstance(MyController.class.getName());myController.test();}
}
GitHub
手撕SpringIOC
相关文章:
自己写一个简单的IOC
什么是SpringIOC? 答:IOC即控制反转,就是我们不在手动的去new一个对象,而是将创建对象的权力交给Spring去管理,我们想要一个User类型的对象,就只需要定义一个User类型的变量user1,然后让Spring去…...
用Python批量重命名文件
案例 今天,我们来整理文件夹中的文件,给某个文件夹下的所有文件重新命名。要求是给所有文件按照修改时间,按顺序在文件名前面加上编号。比如将文件资料.xlsx重命名为1. 资料.xlsx import osdef Get_modify_time(file):return os.path.getmtime(file) #获取文件修改时间path…...
iis之web服务器搭建、部署(详细)~千锋
目录 Web服务器 部署web服务器 实验一 发布一个静态网站 实验二 一台服务器同时发布多个web站点 网站类型 Web服务器 也叫网页服务或HTTP服务器web服务器使用的协议是HTTPHTTP协议端口号:TCP 80、HTTPS协议端口号:TCP 443Web服务器发布软件&…...
javascript的ajax
学什么Ajax基础JSON跨域XHR对象Ajax进阶Ajax应用Ajax扩展Ajax基础初识 AjaxAjax的基本用法GET请求POST请求JSON初识JSONJSON的3种形式JSON的常用方法跨域初识跨域CORS跨域资源共享JSONPXHR 对象XHR的属性XHR的方法XHR的事件Ajax进阶FormData封装Ajax使用Promise改造封装好的Aja…...
SpringBoot入门 - 开发中还有哪些常用注解
本文主要介绍一些SpringBoot中常用的注解。Spring Boot 常用注解SpringBootApplicationTarget(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented Inherited Configuration EnableAutoConfiguration ComponentScan public interface SpringBootApplication {/*…...
网络基础(三)
目录 网络层与数据链路层 编辑 网络层 IP协议 IP的构成 TCP和IP各自解决什么问题? 基本概念 协议头格式 协议头分析 如何分离与封装? 如何分用(向上交付)? 16位首部校验和 32位源IP和目的IP 4位版本 8位服务类型(Type Of…...
Go语言函数高级篇
Go语言函数高级篇1.高阶函数函数作为参数函数作为返回值2.匿名函数3.defer4.内置函数1.高阶函数 高阶函数分为函数作为参数和函数作为返回值两部分。 函数作为参数 函数可以作为参数: package mainimport "fmt"func add(x, y int) int {return x y }…...
ubuntu16.04 python代码自启动和可执行文件自启动
1 python代码自启动 参考 https://blog.csdn.net/qq_38288618/article/details/104096606 准备好python文件 test.py import time c1 while 1:time.sleep(1)cc1print(c)运行 sudo chmod 777 test.py python3 test.py准备run.sh 文件 #!/bin/bash gnome-terminal -x bash -…...
应用层协议 HTTP HTTPS
目录 应用层 再谈 "协议" 序列化和反序列化 关于 json库 request序列化 request反序列化 response序列化 response反序列化 PS:命令宏 HTTP协议 认识URL urlencode和urldecode HTTP协议格式 HTTP请求 HTTP响应 请求方法 编辑 HT…...
图神经网络 pytorch GCN torch_geometric KarateClub 数据集
图神经网络 安装Pyg 首先安装torch_geometric需要安装pytorch然后查看一下自己电脑Pytorch的版本 import torch print(torch.__version__) #1.12.0cu113然后进入官网文档网站 链接: https://pytorch-geometric.readthedocs.io/en/latest/install/installation.html 安装自己…...
【博学谷学习记录】超强总结,用心分享丨人工智能 自然语言处理 文本特征处理小结
目录文本特征处理作用常见的文本特征处理方法添加n-gram特征说明提取n-gram文本长度规范说明实现导包问题记录心得文本特征处理作用 文本特征处理包括为语料添加具有普适性的文本特征, 如:n-gram特征 以及对加入特征之后的文本语料进行必要的处理, 如: 长度规范. 这些特征处…...
2023年中职网络安全竞赛解析——隐藏信息探索
隐藏信息探索 需求环境可私信博主,求个三连! 1.访问服务器的FTP服务,下载图片QR,从图片中获取flag,并将flag提交; 2.访问服务器的FTP服务,下载文件document,从文件中获取flag,并将flag提交; 3.访问服务器的FTP服务,下载图片beach,从图片中获取flag,并将flag提交…...
实用操作--迁移到Spring Boot 3 和 Spring 6 需要关注的JAVA新特性
正如你所了解到的,迁移到Spring Boot 3 或 Spring 6也将迁移到Java 17和Jakarta EE 9。 如果你非常重视可观察性和本机可执行文件,将从Spring Boot 和 Spring 的主要发行版中获益最大。 本文针对迁移到Spring Boot 3 或 Spring 6涉及的变化进行了梳理和总结。 1. java17新特…...
等保检测风险处理方案
文章目录等保检测风险处理方案1. Apache HTTP Server "httpOnly" Cookie信息泄露漏洞(CVE-2012-0053))2. 检测到目标web应用表单存在口令猜测攻击3. X-Content-Type-Options响应头缺失4. X-XSS-Protection响应头缺失5. Content-Security-Policy响应头缺失6. Referrer…...
java 包装类 万字详解(通俗易懂)
前言简介和溯源拆装箱String类和基本类型的相互转化String类和包装类型的相互转化八大包装类的常用方法汇总(含代码演示)一、前言 : 本节内容是我们《API-常用类》专题的最后一节了。本节内容主要讲包装类,内容包括但不限于包装类的诞生&…...
为什么我复制的中文url粘贴出来会是乱码的? 浏览器url编码和解码
为什么我复制的中文url粘贴出来会是乱码的? 浏览器url编码和解码 Start 番茄最近涉及到一些和单点登录相关的业务需求,在实现功能的过程中,难免少不了和 url 打交道。但是在打交道的过程中,遇到一个痛点:明明我复制的…...
移动端适配
是看的b站一个老哥的视频,做的汇总,讲的嘎嘎棒。视频链接:b站链接 视口viewport pc端视口就是可视化的窗口,不包含浏览器工具栏但是移动端,不太一样,布局的视口和可见的视口是不太一样的 移动端的网页…...
【FPGA】Verilog:时序电路应用 | 序列发生器 | 序列检测器
前言:本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例:序列发生器与序列检测器 功能特性: 采用 Xilinx Artix-7 XC7A35T芯片 配置方式:USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器…...
Biomod2 (下):物种分布模型建模
这里写目录标题1.给出一个线性回归模型并求出因子贡献度2.biomod22.1 pseudo-absences:伪不存在点(PA)2.1.1 random2.2.2 disk2.2.3 user.defined method3.使用网格划分区域3.1 计算质心4. 完整案例1.给出一个线性回归模型并求出因子贡献度 ##---------…...
Linux性能学习(2.2):内存_进程线程内存分配机制探究
文章目录1 进程内存分配探究1.1 代码1.2 试验过程2 线程内存分配探究2.1 代码2.2 试验过程3 总结参考资料:1. 嵌入式软件开发杂谈(3):Linux下内存与虚拟内存2. 嵌入式软件开发杂谈(1):Linux下最…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
