【手写一个spring】spring源码的简单实现--容器启动

embedded/2024/11/24 3:36:25/

文章目录

  • 前言
    • `applicationContext`初始化的前置操作
    • 获取扫描路径
    • 判断是否是`bean`对象

前言

今天开启一个新的章节,手写一个简易版的spring,帮助大家对spring能有一个更深层次的理解.
我将分为以下几个章节进行学习:

在这里插入图片描述
今天先开启我们的第一个章节:容器启动.

applicationContext初始化的前置操作

我们在日常使用spring的时候,一般会向容器传入一个配置类或者配置文件,在配置类或者配置文件中,存放扫描路径.在这里我们使用配置类的方式进行设计.

  1. 自定义启动类BaiLuApplicationContext:
public BaiLuApplicationContext(Class configClass) {
//....
}
  1. 自定义配置类
@ComponentScan("com.fbl.service")
public class AppConfig {
//.....
}

在配置类中需要进行扫描路径的确定,我们采用注解(@ComponentScan)的方式设置一个扫描路径
3. 自定义@ComponentScan

@Retention(RetentionPolicy.RUNTIME)//注解生效时机
@Target(ElementType.TYPE)   //写在类上面的注解
public @interface ComponentScan {String value() default "";//存放扫描路径
}
  1. 自定义Component
@Retention(RetentionPolicy.RUNTIME)//生效时间
@Target(ElementType.TYPE)   //写在类上面的注解
public @interface Component {String value() default "";  //这里是beanName
}

获取扫描路径

容器启动的第一步,先要通过配置类,获取到扫描路径.也就是获取到配置类上的注解@ComponentScanvalue()

 public BaiLuApplicationContext(Class configClass) {this.configClass = configClass;//1.扫描if (configClass.isAnnotationPresent(ComponentScan.class)) {ComponentScan annotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);String path = annotation.value();//扫描路径:com.fbl.service//...}        
  • isAnnotationPresent:类中是否存在某个注解
  • getAnnotation:获取到类的某个注解类

这里,我们获取到路径com.fbl.service,该路径就是我们真正需要的路径吗?
答案是否定的.因为我们真正想要扫描的是字节码文件,所以我们需要编译之后的字节码文件的路径,那么我们应该如何获取到这个路径呢?

			String path = annotation.value();   //扫描路径:com.fbl.servicepath=path.replace(".","/");    //com/fbl/serviceClassLoader classLoader = BaiLuApplicationContext.class.getClassLoader();//获取到类加载器URL resource = classLoader.getResource(path);   //通过相对路径(com/fbl/service)获取资源File file = new File(resource.getFile()); //转化成文件System.out.println(file); //D:\develop\MyGit\BaiLuSpring\out\production\BaiLuSpring\com\fbl\service
  • 通过配置类的注解@@ComponentScan("com.fbl.service")获取到扫描的包路径;
  • 将扫描的包路径转换成扫描路径:com.fbl.service->com/fbl/service
  • 获取到类加载器,通过相对路径获取到该资源D:\develop\MyGit\BaiLuSpring\out\production\BaiLuSpring\com\fbl\service,这里获取到的就是存放.class文件的文件夹

判断是否是bean对象

我们刚才已经获取到了字节码文件存放的文件夹,接下来,我们要开始判断,该文件夹下,有哪些是需要交给spring来管理的bean对象.
这里采用的方法是判断是否存在@Component注解:

if(file.isDirectory()){File[] files = file.listFiles();for (File f : files) {String fileName = f.getAbsolutePath();System.out.println(fileName);//判断是不是一个类if(fileName.endsWith(".class")){String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));className=className.replace("\\",".");//获取对象try {Class<?> clazz = classLoader.loadClass(className);//传入全限定类名//说明当前存在@Component注解,是一个需要交给spring管理的bean对象if (clazz.isAnnotationPresent(Component.class)) {}}}
  • 遍历获取到的资源文件夹,判断是否是.class文件;
  • 如果是.class文件(是一个类),接下来通过反射的方式获取到当前的类
  • 再来判断是否存在@Component注解.

这样,整个容器的启动大致就完成了,其实我们主要完成了扫描和判断是否是bean对象的工作.那么bean对象是在什么时候被创建的?什么是单例?什么是多例?这些问题将会在接下来的博客文章里进行总结.


http://www.ppmy.cn/embedded/140019.html

相关文章

深度学习:神经网络中的非线性激活的使用

深度学习&#xff1a;神经网络中的非线性激活的使用 在神经网络中&#xff0c;非线性激活函数是至关重要的组件&#xff0c;它们使网络能够捕捉和模拟输入数据中的复杂非线性关系。这些激活函数的主要任务是帮助网络解决那些无法通过简单的线性操作&#xff08;如权重相乘和偏…

django基于django的民族服饰数据分析系统的设计与实现

摘 要 随着网络科技的发展&#xff0c;利用大数据分析对民族服饰进行管理已势在必行&#xff1b;该平台将帮助企业更好地理解服饰市场的趋势&#xff0c;优化服装款式&#xff0c;提高服装的质量。 本文讲述了基于python语言开发&#xff0c;后台数据库选择MySQL进行数据的存储…

实验室管理智能化:Spring Boot技术实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

wpf 事件转命令的方式

1&#xff0c;方式1 <StackPanel Background"Transparent"><StackPanel.InputBindings><KeyBinding Command"{Binding ChangeColorCommand}"CommandParameter"{Binding ElementNamecolorPicker, PathSelectedItem}"Key"{Bi…

springboot基于微信小程序的农产品交易平台

摘 要 随着网络科技的发展&#xff0c;利用小程序对基于微信小程序的农产品交易平台进行管理已势在必行&#xff1b;该系统将能更好地理解用户需求&#xff0c;优化基于微信小程序的农产品交易平台策略&#xff0c;提高基于微信小程序的农产品交易平台效率和质量。本文讲述了基…

工控HMI界面在工业制造领域,普及度越来越高了。

工控 HMI 界面在工业制造领域的普及度确实越来越高。它以直观的图形和简洁的操作方式&#xff0c;为工人提供了便捷的人机交互体验。 通过 HMI 界面&#xff0c;工人可以轻松监控生产设备的运行状态&#xff0c;及时发现并处理故障。它还能实现参数设置和控制指令的下达&#…

大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

海盗王集成网关和商城服务端功能golang版

之前用golang把海盗王的商城服务端和网关服务端都重写了一次。 后来在同时开启网关和商城服务时&#xff0c;发现窗口数量有点多&#xff0c;有时要找到商城窗口比较麻烦。 既然2个都是用golang govcl写的&#xff0c;是不是可以集成到一起&#xff0c;方便使用呢&#xff1f;…