仿写SpringIoc

1.SpringIoc简单注解

1.1 Autowired

package com.qcby.iocdemo1.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

1.2 Component

package com.qcby.iocdemo1.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

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

2.创建一个controller和一个UserService对象,为后面案例展示提供方便

2.1 controller

package com.qcby.iocdemo1.entity;

import com.qcby.iocdemo1.annotation.Autowired;
import com.qcby.iocdemo1.annotation.Component;

@Component
public class TestController {
    @Autowired
    private UserService userService;
    public void test(){
        userService.addUser("zhangsan",18);
    }
}

2.2 UserService

package com.qcby.iocdemo1.entity;

import com.qcby.iocdemo1.annotation.Component;

@Component
public class UserService {

    public void addUser(String name, int age) {
        System.out.println(name);
        System.out.println(age);
    }
}

3.Ioc实现类

package com.qcby.iocdemo1.ioc;

import com.qcby.iocdemo1.annotation.Autowired;
import com.qcby.iocdemo1.annotation.Component;
import jdk.nashorn.internal.ir.ContinueNode;
import org.springframework.objenesis.instantiator.basic.NewInstanceInstantiator;

import java.beans.Beans;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

public class SpringIOC {
    private String basePath;
    private String basePackage;
    private List<String> beanNames;
    private List<String> filePaths;
    private Map<String, Object> beans = new HashMap<>();

    private void initPath() {
        //设置三个包所在文件夹的绝对路径
        basePath = "D:\\gitcode\\IocDemo1\\src\\main\\java\\com\\qcby\\iocdemo1\\";
        //设置包名
        basePackage = "com.qcby.iocdemo1";
    }

    private void scan() throws FileNotFoundException {
        //创建文件夹对象
        File file = new File(basePath);
        //filePaths集合放置的是文件的绝对路径
        filePaths = new ArrayList<>();
        if (file.exists()) {
            Queue<File> queue = new LinkedList<>();
            //放文件夹下的子文件夹及文件
            queue.add(file);
            while (!queue.isEmpty()) {
                File poll = queue.poll();
                //队首文件出队
                if (poll.isDirectory()) {
                    //判断是否为文件夹,如果是把文件夹里的子文件夹和文件放入队列
                    File[] files = poll.listFiles();
                    for (File file1 : files) {
                        queue.add(file1);
                    }
                } else {
                    filePaths.add(poll.getPath());
                    //如果是文件把文件的路径放入filepaths
                }
            }
        } else {
            throw new FileNotFoundException(basePath + "没有找到");
        }
    }

    private void initBeanNames() {
        for (String s : filePaths) {
            //遍历filepaths
            String replace = s.replace(basePath, "");
            //将每个的前缀变成"",变成相对路径
            if (replace.endsWith(".java")) {
                replace = replace.substring(0, replace.length() - 5);
                //文件名以.java结尾的文件,去掉后缀
            }
            char[] chars = replace.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] == '\\') {
                    chars[i] = '.';
                }
            }
            //将文件路径的/变成.
            beanNames.add(basePackage + "." + new String(chars));
            //将路径以保命+文件相对路径的形式添加到路径集合中
        }
    }

    public void initBeans(){
        for (String beanName : beanNames) {
            try {
                Class<?> aClass = Class.forName(beanName);
                //通过路径获取每个类的对象
                Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();
                //获取每个对类的注解
                for (Annotation declaredAnnotation : declaredAnnotations) {
                    //遍历注解,找到注解为component的注解
                    if (declaredAnnotation instanceof Component) {
                        //有的话,把类对象转化为实例对象,按照路径:对象的形式加入beans集合中
                        Object o = aClass.newInstance();
                        beans.put(aClass.getName(), o);
                    }
                }
            } catch (Exception 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) {
                    //遍历注解,判断该注解是否为autowired
                    if (annotation instanceof Autowired) {
                        //获取该属性的类型的名称
                        String name = field.getType().getName();
                        //找到该数据类型的实例对象
                        Object o = beans.get(name);
                        field.setAccessible(true);
                        try {
                            //把实例对象放入该属性中
                            field.set(entry.getValue(), o);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
    public SpringIOC(){
        initPath();
        try {
            scan();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }
        beanNames=new ArrayList<>();
        initBeanNames();
    }
    public Object getInstance(String beanName){
        return beans.get(beanName);
    }
}

4.使用test测试

        SpringIOC springIOC=new SpringIOC();
        springIOC.initBeans();
        TestController instance = (TestController)springIOC.getInstance(TestController.class.getName());
        instance.test();

5.运行结果

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华三m-lag三层转发+VRRP配置案例

目录 一、相关理论介绍 1.1 华三M-LAG介绍 1.2 DRCP协议 1.3 keepalive机制 1.4 MAD机制 1.5 一致性检查功能 二、M-LAG系统建立及工作过程 三、实验组网案例 3.1 组网需求 3.2 组网拓扑 3.3 设备接口及地址规划 四、具体配置命令 4.1 S6850-1的配置 4.2 S6850-2…

【MySQL05】【 undo 日志】

文章目录 一、前言二、undo 日志&#xff08;回滚日志&#xff09;1. 事务 id2. undo 日志格式2.1 INSERT 对应的 undo 日志2.2 DELETE 对应的 undo 日志2.3 UPDATE 对应的 undo 日志2.3.1 不更新主键2.3.2 更新主键 2.3 增删改操作对二级索引的影响2.4 roll_pointer 3. FIL_PA…

移动视野:人工智能的响应式和基于风险的监管框架

随着人工智能 (AI) 能力的不断发展,其监管不能再只是一种优化和缓解措施,或者最大限度地利用创新机会并最大限度地降低危害风险。 人工智能相互交织的社会经济和法律影响需要动态治理安排来识别、应对和预测不断变化的监管要求。 本报告提出了一个框架,该框架不仅可以预测…

【评测有奖】参加 EMR Serverless Spark 产品评测,赢机械键盘、充电宝等礼品!

EMR Serverless Spark是一款云原生、专为大规模数据处理与分析而设计的全托管 Serverless Spark 计算产品。为企业提供了围绕Spark 任务的一站式开发、调试、调度以及运维等产品化服务&#xff0c;极大的简化了数据处理全生命周期的工作流程&#xff0c;使企业更加专注于数据的…

windows免密登录ssh远程主机

每次都需要通过ssh指令和密码访问服务器太难了&#xff0c;有什么办法可以免密吗&#xff1f; –通过配置公钥和密钥 1. 初始化 在windows本地和服务器上运行 ssh-keygen -t rsa此时会返回公钥密钥的路径&#xff0c;比如 此时&#xff0c;authorized_keys就是授权的认证信…

LVS+Nginx高可用集群---Nginx进阶与实战(二)

1.Nginx配置SSL证书提供https访问 大概步骤&#xff1a;云服务器-注册域名-配置SSL证书-下载证书&#xff0c;并且拷贝到nginx的conf目录下。 检查nginx是否含有ssl的模块-安装ssl模块-配置HTTPS模块-配置SSL-主域名可以通过HTTPS访问 配置模版&#xff1a; 添加上开启SSL的代…

java使用poi-tl模版引擎导出word之if判断条件的使用

文章目录 模版中if语句条件的使用1.数据为False或空集合2.非False或非空集合 模版中if语句条件的使用 如果区块对的值是 null 、false 或者空的集合&#xff0c;位于区块中的所有文档元素将不会显示&#xff0c;这就等同于if语句的条件为 false。语法示例&#xff1a;{{?stat…

Java虚拟机笔记

1、JDK&JRE&JVM Java 执行流程 JRE的应用 JDK JDKJREJVM JDK(Java开发环境)&#xff1a;JRE工具(编译器、调试器、其他工具等)类库 编译器&#xff1a;将Java 文件编译为class文件&#xff0c;也是JVM能运行解释的文件 JRE(Java 运行环境)&#xff1a;JVMJava解释…

多点GRE over IPsecVPN模式下nhrp的调优

一、实验目的 在多点GRE over IPsecVPN模式下对nhrp进行调优&#xff0c;在总部开启重定向、在分支开启shortcut 网络拓扑&#xff1a; 二、基础设置 &#xff08;一&#xff09;如图所示配置接口地址和区域&#xff0c;连接PC的接口位于trust区域、连接路由器的接口位于unt…

【VUE基础】VUE3小技巧(持续更新)

一键快速生成自定义vue3模板代码 根据上图打开配置用户代码片段 搜索vue.jsond打开 "Print to console": {"prefix": "vue","body": ["<!-- $0 -->","<template>"," <div></div>&…

轴承垫圈外观检测有什么技巧?

轴承是一种用于支撑旋转机械零件的元件&#xff0c;通常用于减少摩擦和支撑旋转轴的重量。轴承通过在内部部署滚珠、滚柱或滑动体等方式&#xff0c;使轴的旋转更加顺畅&#xff0c;减少摩擦阻力&#xff0c;并支撑轴的重量。轴承广泛应用于各种机械设备中&#xff0c;包括汽车…

软考分数线有3种,低于45分也能拿证!

软考合格分数标准是45分&#xff0c;这个是广泛为人所知的。然而&#xff0c;有些地区即使没有达到45分也可以获得证书&#xff0c;这一点许多考生并不清楚。总的来说&#xff0c;软考的合格标准有三种&#xff01; ● 全国分数线&#xff1a;通常是各科45分及格&#xff0c;证…

Syncthing一款开源去中心化和点对点文件同步工具

Syncthing&#xff1a;一款开源的文件同步工具&#xff0c;去中心化和点对点加密传输&#xff0c;支持多平台&#xff0c;允许用户在多个设备之间安全、灵活地同步和共享文件&#xff0c;无需依赖第三方云服务&#xff0c;特别适合高安全性和自主控制的文件同步场景。 &#x…

人工智能算法工程师(中级)课程1-Opencv视觉处理之基本操作

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程1-Opencv视觉处理之基本操作。OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它提供了各种视觉处理函数&#xff0c;并…

全志A527 T527 android13支持usb摄像头

1.前言 我们发现usb摄像头在A527 android13上面并不能正常使用,需要支持相关的摄像头。 2.系统节点查看 我们查看系统是否有相关的节点生成,发现/dev/video相关的节点已经生成了。并没有问题,拔插正常。 3.这里我们需要查看系统层是否支持相关的相机, 我们使用命令进行…

11个提升Python列表编码效率的高级技巧

Python中关于列表的一些很酷的技巧 1、collections.deque deque(双端队列)非常适合从列表的两端快速添加和删除项目。 2、使用带有if-else条件的列表推导式 使用if-else的列表推导式可以以简洁的方式创建具有条件逻辑的列表。 3、itertools.product itertools.product从两个…

【windows OBS开启直播】Windows搭建RTMP视频流服务(Nginx服务器版)

如果您想在windows 电脑上设置RTMP服务器&#xff0c;并使用VLC播放器播放OBS的直播流&#xff0c;您可以使用一个本地的RTMP服务器软件&#xff0c;如nginx配合nginx-rtmp-module来搭建。下面 详细介绍下如何搭建此视频流服务。 1、安装和配置本地RTMP服务器 步骤1&#xff…

动手学深度学习6.2 图像卷积-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记&#xff0c;以及对课后练习的一些思考&#xff0c;自留回顾&#xff0c;也供同学之人交流参考。 本节课程地址&#xff1a;卷积层_哔哩哔哩_bilibili 代码_哔哩哔哩_bilibili 本节教材地址&#xff1a;6.2. 图像卷积 — 动…

进程,进程的调度,进程的调度算法(详解)ฅ( ̳• · • ̳ฅ)

目录 &#x1f607;进程的概念&#xff1a; &#x1f61a;进程的组成&#xff1a; &#x1f970;进程的调度&#xff1a; 一.进程调度的概念&#xff1a; 二.进程调度的方式&#xff1a; 三.进程调度的时机&#xff1a; &#x1f92a;进程的调度算法&#xff1a; 一.先…

leetcode--二叉树中的最大路径和

leetcode地址&#xff1a;二叉树中的最大路径和 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总…