【框架源码篇 04】Spring源码手写篇-Bean定义配置化

news2024/11/18 23:49:49

Spring源码手写篇-Bean定义配置化

一、Bean定义配置分析

  我们前面实现了手写IoC和AOP的功能,但是我们在使用的时候发现我们的调用代码还是非常的繁琐,会给应用者很不好的体验。

image.png

  上面的代码很直观的看到重复代码很多,要用户设置的内容也很多,低效而且容易出错,这时我们可以看看在Spring中是怎么处理的呢?

一种是通过XML的配置文件方式

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="abean" class="com.study.spring.samples.ABean">
        <constructor-arg type="String" value="abean01" />
        <constructor-arg ref="cbean" />
    </bean>

    <bean id="cbean" class="com.study.spring.samples.CBean">
        <constructor-arg type="String" value="cbean01" />
    </bean>
</beans>

一种是通过注解的方式来处理

@Component
public class AController{

    @Autowired
    private Acc ac;
}

1. XML方式实现

基于XML方式实现我们需要做什么操作呢?

  • 定义XML规范
  • 要写代码来解析XML,完成Bean定义的注册

2.注解方式实现

基于注解方式实现我们需要做什么操作呢?

  • 定义一套注解
  • 要写代码来扫描、解析注解、完成Bean定义注册。

二、Bean定义配置实现

1. XML方法设计

  xml方式的流程如下:

image.png

我们可以自己写一个解析器,专门来解析对应的xml文件

image.png

2. 注解方式设计

2.1 定义相关的注解

  然后我们来看看需要定义的注解有哪些。

  • 类要不要配置为Bean @Component
  • BeanName Scope和Primary @Scope @Primary
  • 工厂方法 工厂Bean @Bean
  • 初始化方法、销毁方法 @PostConstruct @PreDestory
  • 构造参数依赖 @Autowired @Value
  • 属性依赖 @Qualifier

image.png

2.2 扫描解析注册操作

  我们定义了相关注解后,谁来实现扫描注解、解析注解并完成Bean定义注册呢

image.png

先来看如何实现扫描操作

image.png

实现的逻辑应该是递归找出包目录下的所有的.class 文件。

    public void scan(String... basePackages) throws Throwable {
        if (basePackages != null && basePackages.length > 0) {
            for (String p : basePackages) {
				/*
				 1 递归扫描包目录下的.class文件
				 2 组合包路径+class文件名 得到全限定类名
				 3 ClassLoad.load("类名") 得到 Class 对象
				 4 解析Class上的注解,获得Bean定义信息,注册Bean定义
				 */

                //1 递归扫描包目录下的.class文件
                Set<File> classFiles = this.doScan(p);
                //2 得到Class对象,并解析注解、注册Bean定义
                this.readAndRegisterBeanDefintion(classFiles);
            }
        }
    }

然后看看如何来解析类注解

image.png

    private void readAndRegisterBeanDefintion(Set<File> classFiles) throws BeanDefinitionRegistException {
        for (File classFile : classFiles) {
            String className = getClassNameFromFile(classFile);
            try {
                //加载类
                Class<?> clazz = this.getClass().getClassLoader().loadClass(className);
                Component component = clazz.getAnnotation(Component.class);
                if (component != null) {// 标注了@Component注解
                    String beanName = component.value();
                    if (StringUtils.isBlank(beanName)) {
                        beanName = this.generateBeanName(clazz);
                    }
                    GenericBeanDefinition bd = new GenericBeanDefinition();
                    bd.setBeanClass(clazz);

                    //处理Scope
                    Scope scope = clazz.getAnnotation(Scope.class);
                    if (scope != null) {
                        bd.setScope(scope.value());
                    }
                    //处理primary
                    Primary primary = clazz.getAnnotation(Primary.class);
                    if (primary != null) {
                        bd.setPrimary(true);
                    }

                    // 处理构造方法,在构造方法上找@Autowired注解,如有,将这个构造方法set到bd;
                    this.handleConstructor(clazz, bd);

                    //处理方法上的注解(找出初始化、销毁、工厂方法)
                    this.handleMethod(clazz, bd, beanName);

                    // 处理属性依赖
                    this.handlePropertyDi(clazz, bd);

                    // 注册bean定义
                    this.registry.registerBeanDefinition(beanName, bd);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

3.ApplicationContext

  通过上面的设计,我们可以实现注解的方式来定义,但是给用户的整体体验还是不是很好,这时我们可以通过外观模式,为框架定义一个更简单的统一使用界面

image.png

组合为:

image.png

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

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

相关文章

基于springboot实现学生综合测评系统项目【项目源码+论文说明】

基于springboot实现学生综合测评系统演示 摘要 随着信息化时代的到来&#xff0c;管理系统都趋向于智能化、系统化&#xff0c;学生综合测评系统也不例外&#xff0c;但目前国内仍都使用人工管理&#xff0c;学校规模越来越大&#xff0c;同时信息量也越来越庞大&#xff0c;人…

运营商大数据精准营销,击碎你的固化营销思维

大数据精准营销服务是大数据应用的典型场景之一&#xff0c;也是依托大数据和互联网提升企业效率的一种有效手段。但是&#xff0c;在选择大数据服务的很多时候&#xff0c;企业往往要考虑法律与合规的问题&#xff0c;其中比较重要的是数据获取渠道与数据是否脱敏。在所有大数…

CSS 两栏布局

目录 CSS两栏布局&#xff08;左列定宽&#xff0c;右列自适应宽&#xff09; 方法一&#xff1a;浮动margin 方法二&#xff1a;定位margin 方法三&#xff1a;浮动BFC 方法四&#xff1a;Flex布局 方法五&#xff1a;able布局 CSS两栏布局&#xff08;左列不定宽&#…

一、Qt简介

1. 什么是Qt&#xff1f; Qt是一个基于C的图形用户界面&#xff08;GUI&#xff09;开发框架&#xff0c;但图形用户界面并不是Qt的全部&#xff0c;因为Qt还包含了很多非图形化的开发功能&#xff1a;多线程、数据库、图像图形处理、音视频处理、网络通信、文件IO等。 一方面…

【智慧工地源码】基于AI视觉技术赋能智慧工地

伴随着技术的不断发展&#xff0c;信息化手段、移动技术、智能穿戴及工具在工程施工阶段的应用不断提升&#xff0c;智慧工地概念应运而生&#xff0c;庞大的建设规模催生着智慧工地的探索和研发。 建筑施工具有周期长、环境复杂、工序繁杂、人员流动性大等特点&#xff0c;所以…

10个基于.Net开发的Windows开源软件项目

分享10个适合程序员的神器&#xff0c;都是基于.Net开发的&#xff0c;可以用来学习&#xff0c;日常工作也可以使用。&#xff08;点击标题&#xff0c;查看详情&#xff09; 1、基于.NET的强大文件格式开源转换工具 一个基于.NET平台的开源文件格式转换工具&#xff0c;可以…

仿写el-upload组件,彻底搞懂文件上传

用了那么久的Upload组件&#xff0c;你知道是怎么实现的么&#xff0c;今天就来仿写一个饿了么el-upload vue组件&#xff0c;彻底搞懂前端的文件上传相关知识&#xff01; 要实现的props 参数说明action必选参数&#xff0c;上传的地址headers设置上传的请求头部multiple是否…

Linux内存管理(2):memblock

一、memblock分配器初始化 在内核初始化过程中也需要分配内存,使用的页帧分配器叫memblock(早期的内核版本使用BootMem,新版本内核已不再用)。 memblock是系统启动过程中的一个中间阶段的内存管理, 负责在系统上电到内核内存管理模型初始化之前这段时间的物理内存分配、预留…

mac 升级node到指定版本

node版本14.15.1升级到最新稳定版18.18.2 mac系统 先查看一下自己的node版本 node -v开始升级 第一步 清除node的缓存 sudo npm cache clean -f第二步 安装n模块【管理模块 n是管理 nodejs版本】 sudo npm install -g n第三步升级node sudo n stable // 把当前系统的 Node…

C++初阶(五)类和对象

文章目录 一、C两大类型二、类的6个默认成员函数三、构造函数1、概念2、特性1、构造函数自动调用特性演示2、无参有参调用两种情况演示3、函数重载演示4、默认构造函数组成及演示5、内置类型成员不初始化的补丁演示 3、析构函数1、概念2、特性1、代码演示2、析构两种情况 4、构…

Android MQTT连接阿里云使用Json解析数据

Android Studio 连接阿里云订阅主题然后使用JSON解析数据非常好用 导入MQTT的JAR包1、在项目中添加依赖然后使用Studio 去下载库2、直接下载JAR包&#xff0c;然后作为库进行导入 环境验证&#xff1a;给程序进行联网权限XML布局文件效果如下&#xff1a; MainActitive.java 主…

PTrade财务数据获取函数的问题

前文介绍了PTrade的get_fundamentals函数&#xff0c;可以用于获取股票的财务数据。但在实际应用中&#xff0c;会遇到如下的问题。 前文我们通过将回测时间设置为2023-05-05进行回测调用get_fundamentals&#xff0c;得到如下查询结果&#xff1a; secu_codepubl_dateend_da…

ThingsBoard 实现设备认领

1. 设备认领的使用场景 设备认领在一种场景下使用,当租户已经生产好设备时,租户把设备卖给了客户, 客户通过认领的方式将设备划分到自己下面,客户变成设备的拥有者。 2. 设备认领的方式 设备认领的方式存在两种: 设备生成密钥 和 服务端生成密钥 2.1. 设备生成密钥 设备…

Zookeeper+Hadoop+Spark+Flink+Kafka+Hbase+Hive 完全分布式高可用集群搭建(保姆级超详细含图文)

说明: 本篇将详细介绍用二进制安装包部署hadoop等组件&#xff0c;注意事项&#xff0c;各组件的使用&#xff0c;常用的一些命令&#xff0c;以及在部署中遇到的问题解决思路等等&#xff0c;都将详细介绍。 1.环境说明 1.1 ip规划 iphostname192.168.1.11node1192.168.1.…

来看看如何使用Proton_实现网络聚合_利用安全的网络协议实现网络通讯---工具箱工作笔记001

首先要去注册proton.com 注册的时候首先去注册一个proton的邮箱@protonmail.com这个邮箱 注册以后进入,然后选择中文 然后再去下载这个CDN加速网址 去下载了以后 选择左侧免费的就可以了

升级版多功能版在线WEB工具箱PHP源码/在线站长工具箱源码/php多功能引流工具箱源码

源码简介&#xff1a; 升级版多功能版在线WEB工具箱PHP源码&#xff0c;这是最新的在线站长工具箱源码&#xff0c;它是一款PHP多功能引流工具箱源码。作为一个多功能的Web工具PHP脚本&#xff0c;包含45种工具&#xff0c;适用于平常任务和开发人员&#xff0c;或者用来推广引…

公有云厂商---服务对照表

各厂商特点&#xff1a; Compute: Network: Storage: Database: Migration Tool: Identify: WAF: 来源&#xff1a;https://comparecloud.in/

p-limit源码解读--30行代码,高大上解决Promise的多并发问题

背景 提起控制并发&#xff0c;大家应该不陌生&#xff0c;我们可以先来看看多并发&#xff0c;再去聊聊为什么要去控制它 多并发一般是指多个异步操作同时进行&#xff0c;而运行的环境中资源是有限的&#xff0c;短时间内过多的并发&#xff0c;会对所运行的环境造成很大的…

《算法通关村第二关——指定区间反转问题解析》

《算法通关村第二关——指定区间反转问题解析》 题目描述 给你单链表的头指针head和两个整数left和right&#xff0c;其中left < right 。 请你反转从位置left到位置right的链表节点&#xff0c;返回反转后的链表。 示例1&#xff1a; 输入&#xff1a; head [1,2,3,4,5…

打工人必备技能——找资源~

让我看看还有哪个打工人不会找资源&#xff0c;不过没关系&#xff0c;相信看完我这篇内容&#xff0c;不会的也学会了&#xff01; 一、XDown 全网1000平台视频解析下载器&#xff0c;在线视频下载工具&#xff0c;几乎能下全网所有平台的视频&#xff0c;而且下完还能自由转…