【仿写spring之ioc篇】二、bean生命周期中的创建以及属性赋值

news2024/9/21 0:46:25

扫描类

这个类就不多说了,基本所有框架都要有这一步,这里主要关注我们目前要实现的方法,其他的具体方法可以查看源码

isComponent方法

	/**
     * 扫描所有带有@Component注解的java类,放入到BeanRegistry
     *
     * @return boolean
     */
    public boolean isComponent(String name) throws ClassNotFoundException, NoSuchMethodException {
        Class<?> clazz = Class.forName(name);
        Component annotation = clazz.getAnnotation(Component.class);
        return annotation != null;
    }

getValuedField方法

	/**
     * 获取有value注解的属性
     *
     * @param clazz
     * @return {@link List}<{@link Field}>
     */
    public List<Field> getValuedField(Class<?> clazz){
        List<Field> valuedFieldList = new ArrayList<>();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Value annotation = declaredField.getAnnotation(Value.class);
            if (annotation != null){
                valuedFieldList.add(declaredField);
            }
        }
        return valuedFieldList;
    }

工厂类

这个类目前就是用来管理所有的bean对象,存放方式是map,key是beanName,value是bean对象。需要注意的就是扫描到@Value注解时的处理方法,需要通过拼接set的形式来实现

package com.ez4sterben.spring.ioc.factory.support;

import com.ez4sterben.spring.ioc.annotation.Value;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * bean工厂,储存所有的bean对象
 *
 * @author ez4sterben
 * @date 2023/08/31
 */
public class BeanFactory {

    /**
     * 储存bean实例
     */
    private final Map<String, Object> beanMap = new HashMap<>(256);

    /**
     * 创建bean
     *
     * @param beanClass
     * @return {@link T}
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public <T> T createBean(Class<T> beanClass) throws InstantiationException, IllegalAccessException {
        return beanClass.newInstance();
    }

    /**
     * 调用set方法
     *
     * @param object
     * @param valuedField
     * @return {@link Object}
     */
    public Object doSet(Object object, List<Field> valuedField) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<?> clazz = object.getClass();
        for (Field field : valuedField) {
            Value annotation = field.getAnnotation(Value.class);
            String value = annotation.value();
            Method method = clazz.getMethod(parseSetter(field.getName()),String.class);
            method.invoke(object,value);
        }
        return object;
    }

    /**
     * 解析set方法
     * @param fieldName
     * @return {@link String}
     */
    public String parseSetter(String fieldName){
        String substring = fieldName.substring(0, 1);
        String s = substring.toUpperCase();
        return "set" + s + fieldName.substring(1);
    }
}

启动类

启动类中打印一下调用赋值方法之后的bean对象看一下效果

package com.ez4sterben.spring.test;

import com.ez4sterben.spring.ioc.annotation.BeanScanner;
import com.ez4sterben.spring.ioc.factory.aware.ApplicationContextAware;
import com.ez4sterben.spring.ioc.factory.aware.BeanFactoryAware;
import com.ez4sterben.spring.ioc.factory.aware.BeanNameAware;
import com.ez4sterben.spring.ioc.factory.support.BeanFactory;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 主要
 *
 * @author ez4sterben
 * @date 2023/09/01
 */
public class Main {

    public static void main(String[] args) throws Exception {
        // 1.调用扫描类,加载所有bean
        BeanScanner beanScanner = new BeanScanner();
        BeanFactory beanFactory = new BeanFactory();
        List<String> allJavaFile = beanScanner.getAllJavaFile("F:\\projects\\gitProject\\spring-all\\src\\main\\java\\com\\ez4sterben\\spring\\test");
        // 2.判断是否有Component
        for (String name : allJavaFile) {
            if (beanScanner.isComponent(name)) {
                // 3.是Component就开始bean的生命周期
                Class<?> clazz = beanScanner.getClazz(name);
                // 创建bean
                Object bean = beanFactory.createBean(clazz);
                // 查看@Value注解
                // 1.找到所有@Value的字段
                List<Field> valuedField = beanScanner.getValuedField(clazz);
                // 2.调用set方法
                beanFactory.doSet(bean, valuedField);
                System.out.println(bean);
                // Aware
                // 1.检查是否实现了Aware接口
                // BeanNameAware

                // BeanFactoryAware

                // ApplicationContextAware

                // BeanPostProcessor

                // @PostConstruct

                // InitializingBean

                // BeanPostProcessor

                // using
            }
        }

    }
}

测试类

package com.ez4sterben.spring.test;

import com.ez4sterben.spring.ioc.annotation.Component;
import com.ez4sterben.spring.ioc.annotation.Value;
import com.ez4sterben.spring.ioc.factory.aware.BeanNameAware;
import lombok.Data;

/**
 * 测试组件
 *
 * @author ez4sterben
 * @date 2023/09/01
 */
@Component
@Data
public class TestComponent implements BeanNameAware {
    @Value("ez4sterben")
    private String name;
    private String age;

}

测试结果

在这里插入图片描述
可以看到我们成功的给对象赋值了

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

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

相关文章

【前端demo】圣诞节灯泡 CSS动画实现轮流闪灯

文章目录 效果过程灯泡闪亮实现&#xff08;animation和box-shadow&#xff09;控制灯泡闪亮时间和顺序&#xff08;animation-delay&#xff09;按钮开关 代码htmlcssjs 参考代码1代码2 前端demo目录 效果 效果预览&#xff1a;https://codepen.io/karshey/pen/zYyBRWZ 参考…

初出茅庐的小李博客之STM32F103C8T6音乐控制器实战教程【1】

STM32F103C8T6音乐控制器实战教程[1] USB简单介绍&#xff1a; "USB"代表通用串行总线&#xff08;Universal Serial Bus&#xff09;&#xff0c;是一种用于连接计算机及其外部设备的标准接口。USB接口允许各种设备&#xff08;如打印机、存储设备、键盘、鼠标、摄…

为何电商行业都在争相使用WhatsApp引流小挂件?

WhatsApp小挂件是嵌入在网站上的聊天小部件&#xff0c;允许访问者同WhatsApp与您联系。点击后&#xff0c;它会将客户带到移动或桌面 WhatsApp应用程序&#xff0c;或者直接打开一个对话框&#xff0c;客户可以在这些地方与您发起对话。让我们看看在您的网站上拥有WhatsApp聊天…

Java实现MQTT订阅发布

一. MQTT 与 EMQX MQTT 是轻量级基于代理的发布/订阅的消息传输协议。使用发布/订阅消息模式&#xff0c;提供一对多的消息发布&#xff0c;解除应用程序耦合。底层使用 TCP/IP 提供网络连接。 EMQ X (Erlang/Enterprise/Elastic MQTT Broker) 是基于 Erlang/OTP 平台开发的开…

Vue+Element-ui实现表格本地导入

表格文件存储在前端 如图&#xff0c;表格文件template.xlsx存储在public下的static文件夹下 注意这里的路径容易报错 a链接下载文件失败的问题(未发现文件&#xff09; a.href ‘./static/template.xlsx’ 写的时候不能带public&#xff0c;直接这么写就可以 DownloadTemp…

星域的庞大规模已经让我们眩晕

有一句道格拉斯亚当斯的名言银河系漫游指南我最近想了很多。“空间很大&#xff0c;”他写道。“你不会相信它有多么巨大&#xff0c;令人难以置信。我的意思是&#xff0c;你可能认为去药店的路很长&#xff0c;但那只是去太空的小钱。” 星域不妨把这句引言放在其设计文档的封…

从天镜大模型,透视马上消费的“三重价值”

AI正在打开新世界。 红杉资本曾发表名为《生成式AI&#xff1a;一个创造性的新世界》的文章&#xff0c;提到生成式AI将涉及数十亿的人工劳动力&#xff0c;并促使这些人工劳动力的效率和创造力至少提高10%&#xff0c;有潜力产生数万亿美元的经济价值。 大模型&#xff0c;被…

2 | Window 搭建单机 Hadoop 和Spark

搭建单机 Hadoop 和 Spark 环境可以学习和测试大数据处理的基础知识。在 Windows 操作系统上搭建这两个工具需要一些配置和设置,下面是一个详细的教程: 注意: 在开始之前,请确保你已经安装了 Java 开发工具包(JDK),并且已经下载了 Hadoop 和 Spark 的最新版本。你可以从…

程序员:你如何写可重复执行的SQL语句?

上图的意思&#xff1a; 百战百胜&#xff0c;屡试不爽。 故事 程序员小张&#xff1a; 刚毕业&#xff0c;参加工作1年左右&#xff0c;日常工作是CRUD 架构师老李&#xff1a; 多个大型项目经验&#xff0c;精通各种开发架构屠龙宝术&#xff1b; 小张注意到&#xff0c;在…

【Datawhale】AI夏令营第三期——基于论文摘要的文本分类笔记(下)

笔记上部分请看【Datawhale】AI夏令营第三期——基于论文摘要的文本分类笔记(上) 文章目录 一、深度学习Topline1.1 数据预处理1.2 模型训练1.3 评估模型1.4 测试集推理1.5 后续改进 二、大模型Topline2.1 大模型介绍2.2 大模型是什么&#xff1f;2.3 大模型的原理2.4 大模型可…

嵌入式部署机器学习模型---TinyML

我们目前生活在一个被机器学习模型包围的世界。在一天中&#xff0c;您使用这些模型的次数比您意识到的要多。诸如浏览社交媒体、拍照、查看天气等日常任务都依赖于机器学习模型。您甚至可能会看到此博客&#xff0c;因为机器学习模型向您推荐了此博客。 我们都知道训练这些模型…

【位运算】leetcode371:两整数之和

一.题目描述 两整数之和 二.思路分析 题目要求我们实现两整数相加&#xff0c;但是不能使用加号&#xff0c;应该立马想到是用位运算来解决问题。之前说过&#xff0c;异或就是“无进位相加”&#xff0c;故本题可以先将两数异或&#xff0c;然后想办法让得到的结果进位即可。…

yolov5自定义模型训练三

经过11个小时cpu训练完如下 在runs/train/expx里存放训练的结果&#xff0c; 测试是否可以检测ok 网上找的这张识别效果不是很好&#xff0c;通过加大训练次数和数据集的话精度可以提升。 训练后的权重也可以用视频源来识别&#xff0c; python detect.py --source 0 # webca…

WOFOST模型与PCSE模型技术应用

实现作物产量的准确估算对于农田生态系统响应全球变化、可持续发展、科学粮食政策制定、粮食安全维护都至关重要。传统的经验模型、光能利用率模型等估产模型原理简单&#xff0c;数据容易获取&#xff0c;但是作物生长发育非常复杂&#xff0c;中间涉及众多生理生化过程&#…

Ansible-playbook条件语句when的使用

目录 when关键字1.基本使用2.比较运算符3.逻辑运算符4.判断变量 when关键字 1.基本使用 当ansible_os_family是redhat的时候&#xff0c;执行安装vim&#xff0c;不是的话跳过 --- - hosts: webtasks:- name: Install VIM via yumyum:name: vim-enhancedstate: installedwhe…

mac安装brew

mac安装brew 安装brew 安装brew 第一步&#xff1a;执行. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"第二步&#xff1a;输入开机密码 第三步&#xff1a;回车继续。等待安装完成 第四步&#xff1a;根…

最新盘点!上海值得加入的互联网公司有哪些?(文末附招聘岗位)

暑假结束了&#xff0c;除了迎来了青春热烈的开学季以外&#xff0c;也带来了打工人备受期待的金九银十秋招季。 我们在找工作时&#xff0c;每个人都期待能遇到一个“神仙公司”&#xff0c;譬如丰厚的薪水、优越的晋升通道、融洽的同事关系、良好的work-life balance以及自由…

KubeSphere 社区双周报 | KubeKey 新增网络插件 Hybridnet | 2023.08.18-08.31

KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者&#xff0c;并对近期重要的 PR 进行解析&#xff0c;同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为&#xff1a;2023.08.18-2023.…

Stable Diffusion中的ControlNet插件

文章目录 ControlNet的介绍及安装ControlNet的介绍ControlNet的安装 ControlNet的功能介绍ControlNet的应用与演示 ControlNet的介绍及安装 ControlNet的介绍 ControlNet 的中文就是控制网&#xff0c;本质上是Stable Diffusion的一个扩展插件&#xff0c;在2023年2月份由斯坦…

红米手机使用google play

开启&#xff1a; 1.在 Google Play 支持的设备列表内的小米/红米手机已预装谷歌服务&#xff0c;我们只需要安装Play 商店。 1.开启谷歌服务: 设置 -> 帐号与同步 > 谷歌基础服务 2.安装 Play 商店: 在应用商店搜索 [google play] &#xff0c;安装[Google Play 商店] …