当前位置: 首页 > news >正文

自己写一个简单的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&#xff1f; 答&#xff1a;IOC即控制反转&#xff0c;就是我们不在手动的去new一个对象&#xff0c;而是将创建对象的权力交给Spring去管理&#xff0c;我们想要一个User类型的对象&#xff0c;就只需要定义一个User类型的变量user1&#xff0c;然后让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协议端口号&#xff1a;TCP 80、HTTPS协议端口号&#xff1a;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各自解决什么问题&#xff1f; 基本概念 协议头格式 协议头分析 如何分离与封装&#xff1f; 如何分用(向上交付)&#xff1f; 16位首部校验和 32位源IP和目的IP 4位版本 8位服务类型(Type Of…...

Go语言函数高级篇

Go语言函数高级篇1.高阶函数函数作为参数函数作为返回值2.匿名函数3.defer4.内置函数1.高阶函数 高阶函数分为函数作为参数和函数作为返回值两部分。 函数作为参数 函数可以作为参数&#xff1a; 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&#xff1a;命令宏 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类和包装类型的相互转化八大包装类的常用方法汇总&#xff08;含代码演示&#xff09;一、前言 : 本节内容是我们《API-常用类》专题的最后一节了。本节内容主要讲包装类&#xff0c;内容包括但不限于包装类的诞生&…...

为什么我复制的中文url粘贴出来会是乱码的? 浏览器url编码和解码

为什么我复制的中文url粘贴出来会是乱码的&#xff1f; 浏览器url编码和解码 Start 番茄最近涉及到一些和单点登录相关的业务需求&#xff0c;在实现功能的过程中&#xff0c;难免少不了和 url 打交道。但是在打交道的过程中&#xff0c;遇到一个痛点&#xff1a;明明我复制的…...

移动端适配

​ 是看的b站一个老哥的视频&#xff0c;做的汇总&#xff0c;讲的嘎嘎棒。视频链接&#xff1a;b站链接 视口viewport pc端视口就是可视化的窗口&#xff0c;不包含浏览器工具栏但是移动端&#xff0c;不太一样&#xff0c;布局的视口和可见的视口是不太一样的 移动端的网页…...

【FPGA】Verilog:时序电路应用 | 序列发生器 | 序列检测器

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;序列发生器与序列检测器 ​ 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器…...

Biomod2 (下):物种分布模型建模

这里写目录标题1.给出一个线性回归模型并求出因子贡献度2.biomod22.1 pseudo-absences:伪不存在点&#xff08;PA&#xff09;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 总结参考资料&#xff1a;1. 嵌入式软件开发杂谈&#xff08;3&#xff09;&#xff1a;Linux下内存与虚拟内存2. 嵌入式软件开发杂谈&#xff08;1&#xff09;&#xff1a;Linux下最…...

安卓集成Google TTS引擎:实现离线中文语音播报的完整实践

1. 为什么需要Google TTS引擎 很多安卓开发者都遇到过这样的需求&#xff1a;在应用中实现文字转语音功能。系统自带的Pico TTS引擎虽然轻量&#xff0c;但最大的痛点就是不支持中文。我去年开发一个盲人辅助应用时就踩过这个坑&#xff0c;测试时发现语音输出全是英文&#xf…...

NeuroKit2深度解析:Python神经生理信号处理的进阶实战指南

NeuroKit2深度解析&#xff1a;Python神经生理信号处理的进阶实战指南 【免费下载链接】NeuroKit NeuroKit2: The Python Toolbox for Neurophysiological Signal Processing 项目地址: https://gitcode.com/gh_mirrors/ne/NeuroKit 在当今神经科学和生物医学工程领域&a…...

Microsoft团队提出“弯曲雅各布天梯”新思路,了解量子数据如何教会AI做更好的化学

来源&#xff1a;ScienceAI 本文约3500字&#xff0c;建议阅读5分钟量子计算机生成精确数据&#xff0c;AI模型学习并实现百万倍加速预测。有时&#xff0c;一个视觉上引人注目的隐喻&#xff0c;足以让你传达一个复杂的观点。2001 年夏天&#xff0c;杜兰大学物理教授 John P.…...

WarcraftHelper:魔兽争霸3终极兼容性工具,轻松实现5大版本完美适配

WarcraftHelper&#xff1a;魔兽争霸3终极兼容性工具&#xff0c;轻松实现5大版本完美适配 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否想让…...

基于GTE文本向量的智能应用开发:快速构建文本分析服务

基于GTE文本向量的智能应用开发&#xff1a;快速构建文本分析服务 1. GTE文本向量技术概览 GTE&#xff08;General Text Embedding&#xff09;文本向量模型是当前中文自然语言处理领域的重要技术突破。这个基于ModelScope的预训练模型能够将文本转换为高维向量表示&#xf…...

效率飙升:基于快马AI将繁琐cmd操作整合为自动化脚本工具

最近在开发过程中&#xff0c;经常需要重复执行一些系统维护和环境配置的cmd命令&#xff0c;每次都要手动输入或者查找历史记录&#xff0c;效率实在太低。于是我开始思考如何把这些零散的cmd命令整合成一个自动化工具&#xff0c;正好发现了InsCode(快马)平台这个神器&#x…...

如何无损提取Python可执行文件?解锁逆向工程新姿势

如何无损提取Python可执行文件&#xff1f;解锁逆向工程新姿势 【免费下载链接】python-exe-unpacker A helper script for unpacking and decompiling EXEs compiled from python code. 项目地址: https://gitcode.com/gh_mirrors/py/python-exe-unpacker 破解打包黑箱…...

最佳论文提名!DancingBox:一台手机,从任意物体捕捉角色动画!

点击下方卡片&#xff0c;关注“CVer”公众号AI/CV重磅干货&#xff0c;第一时间送达点击进入—>【顶会/顶刊】投稿交流群添加微信号&#xff1a;CVer2233&#xff0c;小助手拉你进群&#xff01;扫描下方二维码&#xff0c;加入CVer学术星球&#xff01;可以获得最新顶会/顶…...

学习C语言的第一周

大家好啊&#xff0c;我是一名C语言编程小白。 我计划每周投入14小时学习编程&#xff0c;目标是独立写出上万行代码&#xff0c; 并凭借自己的努力&#xff0c;未来能够加入米哈游。...

7大实战技巧精通DLT Viewer:汽车电子日志分析权威指南

7大实战技巧精通DLT Viewer&#xff1a;汽车电子日志分析权威指南 【免费下载链接】dlt-viewer Diagnostic Log and Trace viewing program 项目地址: https://gitcode.com/gh_mirrors/dl/dlt-viewer 一、认知&#xff1a;揭开DLT Viewer的神秘面纱 在现代汽车电子系统…...