SpringBoot自动配置原理、手写一个xxx-spring-boot-starter

SpringBoot的自动配置是:当项目中使用了一个第三方依赖,如何将第三方依赖中的Bean加载到Spring的IOC容器中,我们就可以做到无需额外的配置,直接使用第三方jar中的Bean。
SpringBoot的理念是“约定大于配置”,只要按照SpringBoot约定的规则来提供第三方的jar,SpringBoot就可以自动扫描jar中的Bean加载到IOC容器中。
先要了解SpringBoot自动配置的原理,才能手写一个xxx-spring-boot-starter

SpringBoot自动配置的原理

当我们在SpringBoot的启动类上使用了@SpringBootApplication注解后,这个注解是一个复合注解

@SpringBootApplication
public class SpringBootTestMystaterApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootTestMystaterApplication.class, args);
}
}

查看这个注解,会看见有一个@EnableAutoConfiguration的注解,这个注解是实现SpringBoot自动配置的关键注解.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
// ...
}

继续查看@EnableAutoConfiguration注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
// ...
}

此注解也是一个复合注解,在此注解中有一个@AutoConfigurationPackage注解,此注解能够实现此项目中启动类所在包及其子包下的Bean的自动注入
还通过@Import注解来导入一个AutoConfigurationImportSelector类,此类是实现第三方依赖中Bean注入的关键类

接下来说的是第三方依赖中要做好的配置
在第三方的依赖中,为了实现让SpringBoot自动配置本依赖,需要在此依赖中定义一个配置类,并使用@Configuration注解标注,在这个配置类中使用@Bean注解将需要注入的Bean实例化并提供出来
在此项目中的resources目录下的META-INF目录下新建spring.factories文件,此文件是一个类似于.properties的文件,通过键值对的形式,value为使用了@Configuration的配置类的全限定名
以上就是第三方依赖需要做的配置

接下来继续回到本项目,导入第三方的starter依赖后,
当项目启动后,上述的AuthoConfigurationImportSelector类就会依靠一个叫做SpringFactoriesLoader的类,此类的作用是扫描所以jar中的META-INF/spring.factories的文件,将所有文件中定义的配置类的全限定名返回,
当拿到这些第三方依赖的配置类,这些配置类中提供了要自动注入的Bean,就可以直接使用第三方依赖中的提供出来的Bean了

手写一个spring-boot-starter

1. 首先创建一个maven项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.liumingkai</groupId>
<artifactId>kkk-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.10</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>

2.创建一个需要自动注入的Bean

package com.liumingkai.service;
import org.springframework.beans.factory.annotation.Value;
/**
* @author 刘明凯
* @version 0.0.1
* @date 2023年4月23日 19:50
*/public class SayHello {
@Value("Mingkai Liu")
private String name;
public void sayHello(){
System.out.println("Hello , My name is " + name);
}
}

3.创建此项目的配置类,将需要注入的类提供出去

package com.liumingkai.auto;
import com.liumingkai.service.SayHello;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author 刘明凯
* @version 0.0.1
* @date 2023年4月23日 19:50
*/@Configuration
public class MyConfiguration {
@Bean
public SayHello sayHello(){
SayHello sayHello = new SayHello();
return sayHello;
}
}

4. 在META-INF/spring.factories文件中指明该项目配置类的全限定名

org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.liumingkai.auto.MyConfiguration

5.将项目打包到本地仓库(利用Maven的install命令)
6.在需要引用的项目中导入此依赖

<dependency>
<groupId>org.liumingkai</groupId>
<artifactId>kkk-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

测试自动注入是否成功

package com.liumingkai;
import com.liumingkai.service.SayHello;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringBootTestMystaterApplicationTests {
@Autowired
private SayHello hello;
@Test
void contextLoads() {
hello.sayHello();
}
}

运行结果,发现成功注入

posted @   秋天Code  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示