【Spring-boot】自己开发一个SpringBoot的starter-->原理详解

一、前言

在日常开发中springboot是我们应用非常普遍的开发框架。springboot可以帮助我们快速的开发一个后端应用,我们只需引入依赖,添加简单的配置就能实现对其他框架的整合。他的奥妙就在于它各种各样的starter。

1.1 starter的作用

SpringBoot这些starter的作用就是根据我们配置,给我们初始化一些整合其他框架时需要初始化的一些bean,并加载到spring容器中。这样就减少了在SSM时代那些繁琐的是xml配置。

1.2 环境信息

依赖 版本
springboot 2.4.10

二、原理

2.1 概述

那么springboot是如何实现通过,通过引入一些jar包的依赖就将这些jar包中定义的spring的bean加载到spring容器中的呢?答案就是spring的SPI机制。

2.2 什么是spi

SPI(Service Provider Interface)就是服务提供接口,它是实现服务解耦,插件自由插拔的一直机制。简单来说,就是通过一些类加载器,去加载classpath下指定目录文件,文件中定义的有需要加载的类的全权限定名,然后这些类会被识别并加载。平时开发中数据库连接驱动的加载和dubbo中都用到了SPI技术。正是使用了SPI技术,才实现了插件和服务的解耦和可插拔。

2.3 Spring的SPI

Spring的SPI使用由SpringFactoriesLoader.loadFactoryNames方法实现的,
它会加载所有依赖的jar包下classPath下META-INF/spring.factories文件,然后将解析properties文件,找到指定名称的配置后返回。
源码如下:

	public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
	
	public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
   
   
		ClassLoader classLoaderToUse = classLoader;
		if (classLoaderToUse == null) {
   
   
			classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
		}
		String factoryTypeName = factoryType.getName();
		return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
	}
	
	/**
	 * spring.factories文件的格式为:key=value1,value2,value3
	 * 从所有的jar包中找到META-INF/spring.factories文件
	 * 然后从文件中解析出key=factoryClass类名称的所有value值
	 */
	private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
   
   
		Map<String, List<String>> result = cache.get(classLoader);
		if (result != null) {
   
   
			return result;
		}

		result = new HashMap<>();
		try {
   
   
			// 取得资源文件的URL
			Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
			// 遍历所有的URL
			while (urls.hasMoreElements()) {
   
   
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				// 根据资源文件URL解析properties文件,得到对应的一组@Configuration类
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值