仿写简单IOC

news2025/1/23 20:13:27

目录

TestController类:

UserService类:

 核心代码SpringIOC:

Autowired和Component注解

SpringIOCTest 类 

​编辑

总结:


TestController类:

@Component
public class TestController {

    @Autowired
    private UserService userService;

    public void test(){
     userService.addUser("我口袋只剩玫瑰一片","此行又山高路远");
    }
}

UserService类:

@Component
public class UserService {

    public void addUser(String a,String b){
        System.out.println(a);
        System.out.println(b);
    }
}

 核心代码SpringIOC:

public class SpringIOC {
    private List<String> beanNames;
    private List<String> filePaths;
    private String basePath;
    private String basePackage;

    private Map<String, Object> beans =new HashMap<>();
    /**
     * 扫描所有的文件信息信息,存到了 filePaths
     */
    private void scan() throws FileNotFoundException {
        File file = new File(basePath);
        filePaths = new ArrayList<>();
        if(file.exists()){
            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+" not found");
        }
       //将路径中所有的文件打印出来 filePaths.forEach(e-> System.out.println(e));
    }

    /**
     * 讲所有的.java结尾的 全限定名放到 beanNames
     */
    public void  initBeanNames(){
        for (String s : filePaths) {
            String replace = s.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));
        }
        beanNames.forEach(System.out::println);
    }

    public void initBeans(){
        for (String beanName : beanNames) {
            try {
                Class<?> aClass = Class.forName(beanName);
                Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();
                for (Annotation declaredAnnotation : declaredAnnotations) {
                    if(declaredAnnotation instanceof Component){
                        //反射:
                        Object o = aClass.newInstance();
                        beans.put(aClass.getName(),o);
                    }
                }
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }

        }

        for (Map.Entry<String, Object> entry : beans.entrySet()) {
            Field[] declaredFields = entry.getValue().getClass().getDeclaredFields();

            for (Field field : declaredFields) {

                Annotation[] declaredAnnotations = field.getDeclaredAnnotations();

                for (Annotation annotation : declaredAnnotations) {
                    if(annotation instanceof Autowired){
                        //field 需要由我们来赋值
                        // 我们所持有的所有对象 在beans中
                        // 根据当前域中的类型的名字:反射
                        String name = field.getType().getName();
                        // 从beans 中获得对应的对象
                        Object o = beans.get(name);
                        field.setAccessible(true);
                        try {
                            field.set(entry.getValue(), o);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }


        }
    }
    public Object getInstance(String beanName) {
        return beans.get(beanName);
    }
    private void initPath(){
        basePath="D:\\imitateIOC\\src\\main\\java\\com\\test\\springioc\\";
        basePackage="com.test.springioc";
    }

    public SpringIOC() {
        initPath();
        try {
            scan();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        beanNames= new ArrayList<>();
        initBeanNames();
    }
}

Autowired和Component注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}



@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}

SpringIOCTest 类 

public class SpringIOCTest {

    @Test
    public void testIOC() throws FileNotFoundException {

        //创建IOC容器
        SpringIOC springIOC = new SpringIOC();
        //初始化容器
        springIOC.initBeans();
        //从容器中获得TestController对象
        TestController instance = (TestController) springIOC.getInstance(TestController.class.getName());
        //调用其方法
        instance.test();
    }
}

总结:

整个环境可以归纳为两个阶段:

第一阶段:处理字符串,获得到类权限的名

第二阶段:根据类权限名创建对应的对象(带有@Component的类才会创建对应的对象),然后再遍历访问我们创建好的对象,判断所有的域是否带有@Autowired,如果有就从Bean中取出对应的对象设置进去。

通篇我们没有写new TestController,new UserService这种代码,都是由反射创建的对象设置进来,这就是这篇代码的基本逻辑。

源码已上传gitee平台:

https://gitee.com/dont-live-in-the-past/copy-ioc.git


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/397029.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RocketMQ如何测试

RocketMQ如何测试MQ简介RocketMQRocketMQ测试点MQ简介 MQ&#xff1a;Message Queue&#xff0c;即消息队列&#xff0c;是一种应用程序之间的消息通信&#xff0c;简单理解就是A服务不断的往队列里发布信息&#xff0c;另一服务B从队列中读取消息并执行处理&#xff0c;消息发…

同步、异步ETL架构的比较

背景介绍&#xff1a; 数据的抽取&#xff0c;转换和加载 (ETL, Extract, Transform, Load) 是构建数据仓库过程中最复杂也是至 关重要的一个步骤&#xff0c;我们通常用两种办法来处理 ETL 流程: 一种是异步(Asynchronous) ETL 方式, 也称为文本文件(Flat file)方式。 另外…

华为云平台架构名词解释

名词解释 网络设备 ISW&#xff08;外网接入交换机&#xff09;&#xff1a;出口交换机&#xff0c;常用于和外网建立静态/BGP路由互联 CSW &#xff08;内网接入交换机&#xff09;&#xff1a;专线接入&#xff08;用户内网骨干&#xff09;交换机&#xff0c;用户自有网络…

一场以数字技术深度影响和改造传统实业的新风口,正在开启

当数字经济的浪潮开始上演&#xff0c;一场以数字技术深度影响和改造传统实业的新风口&#xff0c;正在开启。对于诸多在互联网时代看似业已走入死胡同的物种来讲&#xff0c;可以说是打开了新的天窗。对于金融科技来讲&#xff0c;同样如此。以往&#xff0c;谈及金融科技&…

蓝桥杯-左移右移(2022国赛)

蓝桥杯-左移右移1、问题描述2、解题思路与代码实现2.1 方法一&#xff1a;使用LinkedList双向链表实现(50%)2.2 方法二&#xff1a;使用HashMap左右临界值实现(100%)1、问题描述 小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3,…N 。 之后小蓝对这个数组进行了 M 次操…

TX2配置RealSense D455相机SDK和ros驱动

TX2配置RealSense D455相机SDK和ros驱动1 SDK安装2 RealSense-ros安装3 bug及解决3.1 realsense-viewer显示usb2.13.2 Could not found ddynamic_reconfigure折腾了两天终于把realsense的驱动装好了&#xff0c;尝试了命令安装&#xff0c;源码安装&#xff0c;前前后后搞了三遍…

12.并发编程

1.并发并发&#xff1a;逻辑流在时间时重叠构造并发程序&#xff1a;进程&#xff1a;每个逻辑控制流是一个进程&#xff0c;由内核调度和维护进程有独立的虚拟地址空间&#xff0c;想要通信&#xff0c;控制流必须使用某种显式的进程间通信机制(IPC)I/O多路复用&#xff1a;程…

Linux - 第6节 - 动态库和静态库

1.静态库与动态库概念 静态库&#xff08;.a&#xff09;&#xff1a;程序在编译链接的时候把库的代码拷贝到可执行文件中。程序运行的时候将不再需要静态库。动态库&#xff08;.so&#xff09;&#xff1a;程序在运行的时候才去链接动态库的代码&#xff0c;多个程序共享使用…

【javaEE初阶】第三节.多线程 (进阶篇 ) 死锁

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、"死锁"出现的典型场景二、产生 "死锁" 的必要条件 三、解决 "死锁" 问题的办法 总结前言 今天对于多线程进阶的学习&#…

【MapGIS精品教程】007:MapGIS投影变换案例教程

MapGIS投影变换,包括创建坐标系、定义投影、单点投影、类投影、批量投影。 文章目录 一、创建坐标系1. 创建高斯平面坐标系2. 创建阿尔伯斯投影二、定义投影三、投影变换1. 单点投影2. 类投影3. 批量投影一、创建坐标系 在MagGIS数据库中,有个空间参考系的文件夹,内置了常见…

【tensorflow onnx】TensorFlow2导出ONNX及模型可视化教程

文章目录1 背景介绍2 实验环境3 tf2onnx工具介绍4 代码实操4.1 TensorFlow2与ONNX模型导出4.2 ONNX正确性验证4.3 TensorFlow2与ONNX的一致性检查4.4 多输入的情况4.5 设定输入/输出节点5 ONNX模型可视化6 ir_version和opset_version修改7 ONNX输入输出维度修改8 致谢原文来自于…

【教学典型案例】18.开门小例子理解面向对象

目录一&#xff1a;背景介绍业务场景&#xff1a;业务分析&#xff1a;二&#xff1a;实现思路1、面向过程&#xff1a;2、面向对象&#xff08;抽象、封装、继承、多态&#xff09;3、面向对象&#xff08;抽象、封装、继承、多态、反射&#xff09;三&#xff1a;实现过程1、…

如何在 Istio 中使用 SkyWalking 进行分布式追踪

在云原生应用中&#xff0c;一次请求往往需要经过一系列的 API 或后台服务处理才能完成&#xff0c;这些服务有些是并行的&#xff0c;有些是串行的&#xff0c;而且位于不同的平台或节点。那么如何确定一次调用的经过的服务路径和节点以帮助我们进行问题排查&#xff1f;这时候…

二极管损坏的原因有哪些?

大家好,我是记得诚。 最近项目上肖特基二极管出问题了,概率性损坏,二极管本来是一个很简单的器件,这次重新整理一下,供大家参考。 二极管损坏,个人总结有如下几种情况。 1、过压 在Ta=25℃下,超过二极管的最大反向电压VR,二极管可能会被击穿,导致损坏。 2、过流 …

SpringBoot的基本概念和使用

文章目录一、什么是SpringBoot二、Spring Boot优点三、Spring Boot项目创建四、Spring Boot 配置文件1. yml语法2.properties与yml关系3.多系统的配置五、Spring Boot日志文件1.日志对象2.日志级别日志级别的设置System.out.println VS 日志的两个致命缺点3.日志持久化4.更简单…

[ 常用工具篇 ] windows安装phpStudy_v8.1_X64

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

如何实现大文件断点续传、秒传

大家先来了解一下几个概念&#xff1a; 「文件分块」&#xff1a;将大文件拆分成小文件&#xff0c;将小文件上传\下载&#xff0c;最后再将小文件组装成大文件&#xff1b; 「断点续传」&#xff1a;在文件分块的基础上&#xff0c;将每个小文件采用单独的线程进行上传\下载&…

CobaltStrike密码爆破、伪造上线以及DDos——csIntruder

Git仓库&#xff1a; https://github.com/ljy1058318852/csIntruder0x01 概述 本项目包含CobaltStrike密码爆破、伪造上线以及DDos功能。其中伪造上线支持常见魔改版CS。 This project includes CobaltStrike password blasting, fake online and DDos functions. Among them…

云计算创新展望-精耕细作的超级云计算平台

前言在当今云计算深入各行业、计算量暴增现状之下&#xff0c;云计算生态迎来百花齐放。但用户不希望将所有鸡蛋放在一个篮子里面&#xff0c;因此每个企业都在发展自己的私有云、公有云等多云、混合云结构。因云计算的高灵活性、可扩展性、高性价比&#xff0c;在本地10台服务…

ubuntu的快速安装与配置

文章目录前言一、快速安装二 、基础配置1 Sudo免密码2 ubuntu20.04 pip更新源3 安装和配置oneapi(infort/mpi/mkl) apt下载第一次下载的要建立apt源apt下载&#xff08;infort/mpi/mkl)4 安装一些依赖库等5 卸载WSLpython总结前言 win11系统 ubuntu20.04 提示&#xff1a;以下…