【学习笔记】手写一个简单的 Spring IOC
目录
一、什么是 Spring IOC?
二、IOC 的作用
1. IOC 怎么知道要创建哪些对象呢?
2. 创建出来的对象放在哪儿?
3. 创建出来的对象如果有属性,如何给属性赋值?
三、实现步骤
1. 创建自定义注解
2. 创建 IOC 容器
1. 创建 Bean 定义类
2. 创建 IOC 容器
3. 扫描包
4. 使用自定义注解
5. 在 Servlet 中初始化 IOC 对象
6. 测试
3. 实例化 Bean
测试
4. 设置属性
1. 创建一个Controller
2. 属性赋值
3. 测试
四、使用 Bean
1. 创建获取 Bean 的方法
2. 使用 Bean
3. 测试
五、优化 IOC 容器
一、什么是 Spring IOC?
Spring 的核心之一是 IOC,全称 Inversion Of Control ,控制反转,用来统一管理 Bean
二、IOC 的作用
IOC 的作用就是帮程序员创建 Bean 对象
1. IOC 怎么知道要创建哪些对象呢?
在 xml 配置文件中指定要创建哪些对象,或者使用注解的方式
如果使用注解的方式,需要自定义注解,自定义注解说白了就是告诉 JVM 这个 Bean 不同于其他普通的 Bean ,它有其他的用途,标记一下。
@Component、@Controller、@Service 可以用于创建 Bean 的注解
2. 创建出来的对象放在哪儿?
先记录需要被创建的 Bean 对象的信息,存到 HashMap 中,然后根据 HashMap 中存储的Bean 的信息创建对象,存到IOC容器中
3. 创建出来的对象如果有属性,如何给属性赋值?
使用注解 @Autowired
三、实现步骤
1. 创建自定义注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {String value() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {String value() default "";
}
2. 创建 IOC 容器
扫描包,判断类上是否有注解,如果有,存储需要被创建的对象的id,也就是全类名。
定义一个类用于存储这些信息,这个类就是 BeanDefinition 叫做 Bean 定义类,Bean 定义类创建对象后称为 Bean 定义对象,这个对象存储了 Bean 的信息
然后把 Bean 定义对象存放到 HashMap 中,这个 Map 叫做 Bean 定义Map
1. 创建 Bean 定义类

package com.shao.IOC;public class BeanDefinition {private String id;private String className;public BeanDefinition() {}public BeanDefinition(String id, String className) {this.id = id;this.className = className;}/*** 获取** @return id*/public String getId() {return id;}/*** 设置** @param id*/public void setId(String id) {this.id = id;}/*** 获取** @return className*/public String getClassName() {return className;}/*** 设置** @param className*/public void setClassName(String className) {this.className = className;}public String toString() {return "BeanDefinition{id = " + id + ", className = " + className + "}";}
}
2. 创建 IOC 容器

3. 扫描包
扫描包需要先知道路径是什么,从哪开始
这里扫描的是编译后的 class 文件,并不是类文件,因为程序运行后使用的是编译后的文件

那如何从这里开始呢?
使用类加载器获取路径
package com.shao.IOC;import com.shao.Annotation.Controller;
import com.shao.Annotation.Service;import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;/*** ApplicationContext 类. 当作 IOC 容器** @author shao.*/
public class ApplicationContext {/*** Bean 定义Map 存储Bean 定义对象*/private HashMap<String, BeanDefinition> beanDefinitionMap = new HashMap<>();/*** Bean 实例Map 存储Bean 实例对象*/private HashMap<String, Object> BeanMap = new HashMap<>();public ApplicationContext(String basePackage) throws UnsupportedEncodingException {scanPackage(basePackage);}/*** 1. 扫描包,扫描需要被创建的类,创建 Bean 定义对象,并放入 Bean 定义Map中*/public void scanPackage(String basePackage) throws UnsupportedEncodingException {
// String basePackage = "com.shao";// 获取类加载器ClassLoader classLoader = this.getClass().getClassLoader();// 获取包路径String path = classLoader.getResource(basePackage.replace(".", "/")).getPath();// 路径解码,如果路径有空格或者中文,会出现 16 进制的字符String packagePath = URLDecoder.decode(path, "UTF-8");// 创建文件对象File fileDir = new File(packagePath);// 获取包下的文件列表File[] files = fileDir.listFiles();for (File file : files) {if (file.isFile()) {// 判断是否是class文件if (file.getName().endsWith(".class")) {// 包路径 + 文件名 构成全类名String className = basePackage + "." + file.getName().replace(".class", "");try {// 动态加载了名为 className 的类,获取该类的 Class 对象Class<?> aClass = Class.forName(className);// 判断该类是否有 @Service 或 @Controller 注解if (aClass.isAnnotationPresent(Service.class) ||aClass.isAnnotationPresent(Controller.class)) {System.out.println("需要创建:" + className);// 将该类的类名首字母小写作为 idString id = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);System.out.println("id:" + id);// 创建 Bean 定义对象,并放入 Bean 定义Map中beanDefinitionMap.put(id, new BeanDefinition(id, className));}} catch (ClassNotFoundException e) {e.printStackTrace();}}} else if (file.isDirectory()) {// 递归扫描子文件夹String subPackagePath = basePackage + "." + file.getName();scanPackage(subPackagePath);}}}
}
4. 使用自定义注解

5. 在 Servlet 中初始化 IOC 对象
这里为了方便测试,所以先在 Servlet 中初始化 IOC

6. 测试


3. 实例化 Bean
遍历 Bean 定义Map ,取出 Bean 定义对象,根据对象的信息使用反射技术创建 Bean 对象,这个时候这个 Bean 也叫裸Bean,然后存入 Bean Map 中。这一步在 Bean 的生命周期中属于 Bean 的实例化
package com.shao.IOC;import com.shao.Annotation.Controller;
import com.shao.Annotation.Service;import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;/*** ApplicationContext 类. 当作 IOC 容器** @author shao.*/
public class ApplicationContext {/*** Bean 定义Map 存储Bean 定义对象*/private HashMap<String, BeanDefinition> beanDefinitionMap = new HashMap<>();/*** Bean 实例Map 存储Bean 实例对象*/private HashMap<String, Object> BeanMap = new HashMap<>();public ApplicationContext(String basePackage) throws UnsupportedEncodingException {scanPackage(basePackage);createBean();}/*** 1. 扫描包,扫描需要被创建的类,创建 Bean 定义对象,并放入 Bean 定义Map中*/public void scanPackage(String basePackage) throws UnsupportedEncodingException {// 获取类加载器ClassLoader classLoader = this.getClass().getClassLoader();// 获取包路径String path = classLoader.getResource(basePackage.replace(".", "/")).getPath();// 路径解码,如果路径有空格或者中文,会出现 16 进制的字符String packagePath = URLDecoder.decode(path, "UTF-8");// 创建文件对象File fileDir = new File(packagePath);// 获取包下的文件列表File[] files = fileDir.listFiles();for (File file : files) {if (file.isFile()) {// 判断是否是class文件if (file.getName().endsWith(".class")) {// 包路径 + 文件名 构成全类名String className = basePackage + "." + file.getName().replace(".class", "");try {// 动态加载了名为 className 的类,获取该类的 Class 对象Class<?> aClass = Class.forName(className);// 判断该类是否有 @Service 或 @Controller 注解if (aClass.isAnnotationPresent(Service.class) ||aClass.isAnnotationPresent(Controller.class)) {System.out.println("需要创建:" + className);// 将该类的类名首字母小写作为 idString id = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);System.out.println("id:" + id);// 创建 Bean 定义对象,并放入 Bean 定义Map中beanDefinitionMap.put(id, new BeanDefinition(id, className));}} catch (ClassNotFoundException e) {e.printStackTrace();}}} else if (file.isDirectory()) {// 递归扫描子文件夹String subPackagePath = basePackage + "." + file.getName();scanPackage(subPackagePath);}}}/*** 2. 创建 Bean 实例,并放入 Bean Map 中*/public void createBean() {// 获取 Bean 定义 Map 的 所有 idSet<String> ids = beanDefinitionMap.keySet();Iterator<String> it = ids.iterator();while (it.hasNext()) {String id = it.next();// 获取 Bean 定义对象BeanDefinition beanDefinition = beanDefinitionMap.get(id);// 获取 Bean 定义对象中的 Bean 的全类名String className = beanDefinition.getClassName();try {// 动态加载类,并创建 Bean 实例,这时候的 Bean 是裸BeanObject bean = Class.forName(className).newInstance();// 将 Bean 实例放到 Bean Map 中BeanMap.put(id, bean);} catch (Exception e) {e.printStackTrace();}}System.out.println("实例化 Bean 完成");System.out.println(BeanMap);}
}
测试

4. 设置属性
给Bean 对象做初始化,也就是依赖注入。Bean 的生命周期中属于 Bean 的初始化
这里是使用类作为属性进行依赖注入,不是接口,后续需要优化
1. 创建一个Controller
使用 @Autowired 注解,这里为了方便测试,重写一下 toString 方法

2. 属性赋值
package com.shao.IOC;import com.shao.Annotation.Autowired;
import com.shao.Annotation.Controller;
import com.shao.Annotation.Service;import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;/*** ApplicationContext 类. 当作 IOC 容器** @author shao.*/
public class ApplicationContext {/*** Bean 定义Map 存储Bean 定义对象*/private HashMap<String, BeanDefinition> beanDefinitionMap = new HashMap<>();/*** Bean 实例Map 存储Bean 实例对象*/private HashMap<String, Object> BeanMap = new HashMap<>();public ApplicationContext(String basePackage) throws UnsupportedEncodingException {scanPackage(basePackage);createBean();injectBean();}/*** 1. 扫描包,扫描需要被创建的类,创建 Bean 定义对象,并放入 Bean 定义Map中*/public void scanPackage(String basePackage) throws UnsupportedEncodingException {// 获取类加载器ClassLoader classLoader = this.getClass().getClassLoader();// 获取包路径String path = classLoader.getResource(basePackage.replace(".", "/")).getPath();// 路径解码,如果路径有空格或者中文,会出现 16 进制的字符String packagePath = URLDecoder.decode(path, "UTF-8");// 创建文件对象File fileDir = new File(packagePath);// 获取包下的文件列表File[] files = fileDir.listFiles();for (File file : files) {if (file.isFile()) {// 判断是否是class文件if (file.getName().endsWith(".class")) {// 包路径 + 文件名 构成全类名String className = basePackage + "." + file.getName().replace(".class", "");try {// 动态加载了名为 className 的类,获取该类的 Class 对象Class<?> aClass = Class.forName(className);// 判断该类是否有 @Service 或 @Controller 注解if (aClass.isAnnotationPresent(Service.class) ||aClass.isAnnotationPresent(Controller.class)) {System.out.println("需要创建:" + className);// 将该类的类名首字母小写作为 idString id = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);System.out.println("id:" + id);// 创建 Bean 定义对象,并放入 Bean 定义Map中beanDefinitionMap.put(id, new BeanDefinition(id, className));}} catch (ClassNotFoundException e) {e.printStackTrace();}}} else if (file.isDirectory()) {// 递归扫描子文件夹String subPackagePath = basePackage + "." + file.getName();scanPackage(subPackagePath);}}}/*** 2. 创建 Bean 实例,并放入 Bean Map 中*/public void createBean() {// 获取 Bean 定义 Map 的 所有 idSet<String> ids = beanDefinitionMap.keySet();Iterator<String> it = ids.iterator();while (it.hasNext()) {String id = it.next();// 获取 Bean 定义对象BeanDefinition beanDefinition = beanDefinitionMap.get(id);// 获取 Bean 定义对象中的 Bean 的全类名String className = beanDefinition.getClassName();try {// 动态加载类,并创建 Bean 实例,这时候的 Bean 是裸BeanObject bean = Class.forName(className).newInstance();// 将 Bean 实例放到 Bean Map 中BeanMap.put(id, bean);} catch (Exception e) {e.printStackTrace();}}System.out.println("实例化 Bean 完成");System.out.println(BeanMap);}/*** 3. 给 Bean 设置属性,Autowired 赋值*/public void injectBean() {// 获取 Bean Map 的 所有 idIterator<String> it = BeanMap.keySet().iterator();while (it.hasNext()) {String id = it.next();// 获取 Bean 实例Object bean = BeanMap.get(id);// 获取 Bean 的 Class 对象Class<?> aClass = bean.getClass();// 获取这个类的所有属性,不包括父类的属性Field[] declaredFields = aClass.getDeclaredFields();for (Field field : declaredFields) {// 判断该属性是否有 @Autowired 注解if (field.isAnnotationPresent(Autowired.class)) {// 设置属性可访问field.setAccessible(true);try {// 给属性赋值field.set(bean, BeanMap.get(field.getName()));} catch (IllegalAccessException e) {e.printStackTrace();}}}}System.out.println("属性赋值完成");System.out.println(BeanMap);}
}
3. 测试

四、使用 Bean
1. 创建获取 Bean 的方法
要使用 Bean ,需要从IOC 容器中获取 Bean,所以还需要在 IOC 容器中提供获取 Bean 的接口
package com.shao.IOC;import com.shao.Annotation.Autowired;
import com.shao.Annotation.Controller;
import com.shao.Annotation.Service;import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;/*** ApplicationContext 类. 当作 IOC 容器** @author shao.*/
public class ApplicationContext {/*** Bean 定义Map 存储Bean 定义对象*/private HashMap<String, BeanDefinition> beanDefinitionMap = new HashMap<>();/*** Bean 实例Map 存储Bean 实例对象*/private HashMap<String, Object> BeanMap = new HashMap<>();public ApplicationContext(String basePackage) throws UnsupportedEncodingException {scanPackage(basePackage);createBean();injectBean();}/*** 1. 扫描包,扫描需要被创建的类,创建 Bean 定义对象,并放入 Bean 定义Map中*/public void scanPackage(String basePackage) throws UnsupportedEncodingException {// 获取类加载器ClassLoader classLoader = this.getClass().getClassLoader();// 获取包路径String path = classLoader.getResource(basePackage.replace(".", "/")).getPath();// 路径解码,如果路径有空格或者中文,会出现 16 进制的字符String packagePath = URLDecoder.decode(path, "UTF-8");// 创建文件对象File fileDir = new File(packagePath);// 获取包下的文件列表File[] files = fileDir.listFiles();for (File file : files) {if (file.isFile()) {// 判断是否是class文件if (file.getName().endsWith(".class")) {// 包路径 + 文件名 构成全类名String className = basePackage + "." + file.getName().replace(".class", "");try {// 动态加载了名为 className 的类,获取该类的 Class 对象Class<?> aClass = Class.forName(className);// 判断该类是否有 @Service 或 @Controller 注解if (aClass.isAnnotationPresent(Service.class) ||aClass.isAnnotationPresent(Controller.class)) {System.out.println("需要创建:" + className);// 将该类的类名首字母小写作为 idString id = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);System.out.println("id:" + id);// 创建 Bean 定义对象,并放入 Bean 定义Map中beanDefinitionMap.put(id, new BeanDefinition(id, className));}} catch (ClassNotFoundException e) {e.printStackTrace();}}} else if (file.isDirectory()) {// 递归扫描子文件夹String subPackagePath = basePackage + "." + file.getName();scanPackage(subPackagePath);}}}/*** 2. 创建 Bean 实例,并放入 Bean Map 中*/public void createBean() {// 获取 Bean 定义 Map 的 所有 idSet<String> ids = beanDefinitionMap.keySet();Iterator<String> it = ids.iterator();while (it.hasNext()) {String id = it.next();// 获取 Bean 定义对象BeanDefinition beanDefinition = beanDefinitionMap.get(id);// 获取 Bean 定义对象中的 Bean 的全类名String className = beanDefinition.getClassName();try {// 动态加载类,并创建 Bean 实例,这时候的 Bean 是裸BeanObject bean = Class.forName(className).newInstance();// 将 Bean 实例放到 Bean Map 中BeanMap.put(id, bean);} catch (Exception e) {e.printStackTrace();}}System.out.println("实例化 Bean 完成");System.out.println(BeanMap);}/*** 3. 给 Bean 设置属性,Autowired 赋值*/public void injectBean() {// 获取 Bean Map 的 所有 idIterator<String> it = BeanMap.keySet().iterator();while (it.hasNext()) {String id = it.next();// 获取 Bean 实例Object bean = BeanMap.get(id);// 获取 Bean 的 Class 对象Class<?> aClass = bean.getClass();// 获取这个类的所有属性,不包括父类的属性Field[] declaredFields = aClass.getDeclaredFields();for (Field field : declaredFields) {// 判断该属性是否有 @Autowired 注解if (field.isAnnotationPresent(Autowired.class)) {// 设置属性可访问field.setAccessible(true);try {// 给属性赋值field.set(bean, BeanMap.get(field.getName()));} catch (IllegalAccessException e) {e.printStackTrace();}}}}System.out.println("属性赋值完成");System.out.println(BeanMap);}/*** 对外提供获取 Bean 的接口*/public Object GetBean(String id) {return BeanMap.get(id);}public <T> T GetBean(Class<T> clazz) {// 获取类名,首字母小写String id = clazz.getSimpleName().substring(0, 1).toLowerCase() + clazz.getSimpleName().substring(1);// 获取 Bean 实例Object value = BeanMap.get(id);// 判断 value 是否为 clazz 类型if (clazz.isInstance(value)) {// 安全的转换类型return clazz.cast(value);} else {return null;}}
}
2. 使用 Bean
这里为了方便测试,在Servlet 中获取 Bean,然后调用 Bean 实例的方法

3. 测试



五、优化 IOC 容器
现在需要注入依赖的属性是类,不是接口,需要改成给接口赋值其 实现类的对象
相关文章:
【学习笔记】手写一个简单的 Spring IOC
目录 一、什么是 Spring IOC? 二、IOC 的作用 1. IOC 怎么知道要创建哪些对象呢? 2. 创建出来的对象放在哪儿? 3. 创建出来的对象如果有属性,如何给属性赋值? 三、实现步骤 1. 创建自定义注解 2. 创建 IOC 容器…...
日记学习小迪安全27
感觉复制粘贴没有意思,而且还有点浪费时间,主要是学习,不是复制,那就复制别人的吧 第27关就参考这篇文章吧,以下大部分内容都是参考以下文章(侵权删除) 第27天:WEB攻防-通用漏洞&a…...
【React】类组件和函数组件
构建组件的方式 函数式组件(function)createElement(不建议使用)类组件形式创建(不建议使用) 对于 React 的理解 React, 用于构建用户界面的JavaScript库,本身只提供了Ul层面的解决方案。&am…...
Spring Boot应用开发
Spring Boot是一个基于Spring框架的开源Java框架,旨在简化新Spring应用的初始化和开发过程。它通过提供各种默认配置,减少了繁琐的配置,使开发者能够专注于业务逻辑的实现。本文将介绍Spring Boot的基本概念、优点、关键特性以及如何构建一个…...
mysql事务使用和事务隔离级别与sqlserver的比较
在 MySQL 中,事务 (Transaction) 是一个将一组 SQL 语句作为一个整体执行的机制。事务确保要么所有操作都执行成功,要么在遇到错误时回滚到之前的状态,从而保证数据库数据的一致性和完整性。 事务的四大特性(ACID) 事…...
双光吊舱图像采集详解!
一、图像采集 可见光图像采集: 使用高性能的可见光相机,通过镜头捕捉自然光或人工光源照射下的目标图像。 相机内部通常配备有先进的图像传感器,如CMOS或CCD,用于将光信号转换为电信号。 红外图像采集: 利用红外热…...
1688商品详情关键词数据-API
要利用 Python 爬虫采集 1688 商品详情数据,需要先了解 1688 网站的页面结构和数据请求方式。一般使用 requests 库请求网站的数据,使用 BeautifulSoup 库解析网页中的数据。 以下是一个简单的 Python 爬虫采集 1688 商品详情数据的示例代码:…...
vue 的属性绑定
双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令。 <template> <div v-bind:class"boxClass" v-bind:id"boxId"> </div> </template><script> export default{da…...
【附源码】Python :打家劫舍
系列文章目录 Python 算法学习:打家劫舍问题 文章目录 系列文章目录一、算法需求二、解题思路三、具体方法源码方法1:动态规划(自底向上)方法2:动态规划(自顶向下)方法3:优化的动态…...
YOLO11改进 | 注意力机制| 对小目标友好的BiFormer【CVPR2023】
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 本文介绍了一种新颖的动态稀疏注意力机制…...
高级Python开发工程师的面试备考指南
目录 博客标题:高级Python开发工程师的面试备考指南:30个面试问题与详细解析岗位职责问题解析1. 公司产品功能开发和代码维护2. 技术方案与项目计划制定3. 算法基础与代码优化4. 项目管理与团队协作任职要求问题解析5. Python 开发经验6. 数据处理相关库(Pandas, Numpy, Mat…...
【Java】JAVA知识总结浅析
Java是一门功能强大的编程语言,广泛应用于多个领域。Java的编程思想,包括面向过程和面向对象编程,Java的发展历史,各版本的特点,JVM原理,数据类型,Java SE与Java EE的区别,应用场景&…...
23-云原生监控系统
├──23-云原生监控系统 | ├──1-Prometheus监控 | | ├──1-二进制方式部署Prometheus监控系统 | | ├──2-二进制方式部署Prometheus监控系统告警 | | ├──3-容器化构建Prometheus监控系统 | | ├──4-容器监控方案CAdvisor | | └──5-k8s监…...
信息安全工程师(40)防火墙技术应用
一、防火墙的基本概念 防火墙是一种网络安全设备,用于监控和控制网络流量,以保护网络免受未经授权的访问和攻击。它可以是装配多张网卡的通用计算机,也可能是通用的物理设备。防火墙通过在网络之间设置访问控制策略,对进出的通信流…...
Liquid AI与液态神经网络:超越Transformer的大模型架构探索
1. 引言 自2017年谷歌发表了开创性的论文《Attention Is All You Need》以来,基于Transformer架构的模型迅速成为深度学习领域的主流选择。然而,随着技术的发展,挑战Transformer主导地位的呼声也逐渐高涨。最近,由麻省理工学院(M…...
Spring Boot 进阶-详解Spring Boot中使用Swagger3.0
在上篇文章中我们介绍了Spring Boot 整合Swagger3.0的一些基础用法,这篇文章中我们来深入学习一下Swagger3.0 还有其他高级用法。 在日常的开发中,为了减少工作量,我们会遇到一种情况,就是将前端的接口与后端的接口编写到同一个代码中,这样也提高了代码的复用率,减少了重…...
Linux平台Kafka高可用集群部署全攻略
🐇明明跟你说过:个人主页 🏅个人专栏:《大数据前沿:技术与应用并进》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Kafka简介 2、Kafka核心优势 二、环境准备 1…...
Android中有哪些布局方式?
Android中的布局方式是实现用户界面设计的基础,通过合理的布局,可以创建出美观且易用的应用程序界面。Android提供了多种布局方式,每种布局方式都有其特定的应用场景和特点。以下是对Android中主要布局方式的详细介绍: 一、线性布…...
Apache Ranger 70道面试题及参考答案
什么是Apache Ranger? Apache Ranger Apache Ranger 是一个用于 Hadoop 生态系统的集中式安全管理框架,旨在为 Hadoop 及相关大数据技术提供全面的安全解决方案。 它具有以下主要特点和功能: 一、访问控制管理 细粒度的权限控制:可以对 Hadoop 生态系统中的各种组件(如 H…...
2024年9月30日--10月6日(ue5肉鸽结束,20小时,共2851小时)
按照月计划,本周把ue肉鸽游戏完成,然后进行ue5太阳系 , 剩余14节,218分钟,如果按照10分钟的视频教程1小时进行完的话,则需要22小时,分布在10月2日-10月6日之间,每天44分钟的视频教程…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...
