SpringBoot3 自定义 Starter
SpringBoo3 最简单自定义 Starter 步骤。
1. 启动一个空白模板项目
gradle或者maven项目
引入如下依赖:- implementation("org.springframework.boot:spring-boot-autoconfigure:3.5.0")
复制代码 2. 手写自动配置类
- package edu.tyut.config
- import org.slf4j.Logger
- import org.slf4j.LoggerFactory
- import org.springframework.beans.factory.BeanFactory
- import org.springframework.boot.autoconfigure.AutoConfiguration
- import org.springframework.boot.autoconfigure.AutoConfigurationPackages
- import org.springframework.context.annotation.Bean
- private const val BASE_PACKAGE: String = "basePackage"
- /**
- * custom config
- */
- @AutoConfiguration
- internal open class CustomAutoConfig {
- private val logger: Logger = LoggerFactory.getLogger(this.javaClass)
- @Bean(value = [BASE_PACKAGE])
- internal open fun getBasePackage (
- beanFactory: BeanFactory
- ): String {
- val packages: List<String> = AutoConfigurationPackages.get(beanFactory)
- logger.info("CustomAutoConfig AutoConfiguration Packages: $packages")
- return packages.firstOrNull() ?: "edu.tyut"
- }
- }
复制代码 3. 注册自动配置类
在文件resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports下注册:- edu.tyut.config.CustomAutoConfig
复制代码End, 怎么样是不是非常简单
原理解析
1. 启动类的注解@SpringBootApplication
源码如下:- @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 {
- ...
- }
复制代码 2. @EnableAutoConfiguration
源码如下:- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- @AutoConfigurationPackage
- @Import(AutoConfigurationImportSelector.class)
- public @interface EnableAutoConfiguration {
- ...
- }
复制代码 3. AutoConfigurationImportSelector
源码如下:- public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
- ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
- private final Class<?> autoConfigurationAnnotation;
- AutoConfigurationImportSelector(Class<?> autoConfigurationAnnotation) {
- this.autoConfigurationAnnotation = (autoConfigurationAnnotation != null) ? autoConfigurationAnnotation
- : AutoConfiguration.class;
- }
- ...
- protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
- ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation,
- getBeanClassLoader());
- List<String> configurations = importCandidates.getCandidates();
- Assert.state(!CollectionUtils.isEmpty(configurations),
- "No auto configuration classes found in " + "META-INF/spring/"
- + this.autoConfigurationAnnotation.getName() + ".imports. If you "
- + "are using a custom packaging, make sure that file is correct.");
- return configurations;
- }
- ...
- }
复制代码 代码解读
查看该类构造函数可以发现其有一个成员变量autoConfigurationAnnotation,其值为org.springframework.boot.autoconfigure.AutoConfiguration.
getCandidateConfigurations的参数为即为org.springframework.boot.autoconfigure.AutoConfiguration.
4. org.springframework.boot.context.annotation.ImportCandidates
源码如下:- public final class ImportCandidates implements Iterable<String> {
- ...
- public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {
- Assert.notNull(annotation, "'annotation' must not be null");
- ClassLoader classLoaderToUse = decideClassloader(classLoader);
- String location = String.format(LOCATION, annotation.getName());
- Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
- List<String> importCandidates = new ArrayList<>();
- while (urls.hasMoreElements()) {
- URL url = urls.nextElement();
- importCandidates.addAll(readCandidateConfigurations(url));
- }
- return new ImportCandidates(importCandidates);
- }
- }
复制代码 代码解读:
找到类路径下所有的META-INF/spring/full-qualified-annotation-name.imports文件,读取内容(自动配置类的全限定名), 如果在自动配置类没有org.springframework.boot.autoconfigure.AutoConfiguration注解,会抛出IllegalArgumentException异常。
META-INF/spring/full-qualified-annotation-name.imports文件 -> URL -> BufferedReader -> ImportCandidates.
5. ImportCandidates
ImportCandidates包含了所有的自动配置类,SpringBoot会对其进行进一步的处理。
End 本文分享结束, 有什么不足还请大家指出
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |