找回密码
 立即注册
首页 业界区 安全 SpringBoot3 自定义 Starter

SpringBoot3 自定义 Starter

钱艷芳 昨天 12:28
SpringBoot3 自定义 Starter

SpringBoo3 最简单自定义 Starter 步骤。
1. 启动一个空白模板项目

gradle或者maven项目
引入如下依赖:
  1. implementation("org.springframework.boot:spring-boot-autoconfigure:3.5.0")
复制代码
2. 手写自动配置类
  1. package edu.tyut.config
  2. import org.slf4j.Logger
  3. import org.slf4j.LoggerFactory
  4. import org.springframework.beans.factory.BeanFactory
  5. import org.springframework.boot.autoconfigure.AutoConfiguration
  6. import org.springframework.boot.autoconfigure.AutoConfigurationPackages
  7. import org.springframework.context.annotation.Bean
  8. private const val BASE_PACKAGE: String = "basePackage"
  9. /**
  10. * custom config
  11. */
  12. @AutoConfiguration
  13. internal open class CustomAutoConfig {
  14.     private val logger: Logger = LoggerFactory.getLogger(this.javaClass)
  15.     @Bean(value = [BASE_PACKAGE])
  16.     internal open fun getBasePackage (
  17.         beanFactory: BeanFactory
  18.     ): String {
  19.         val packages: List<String> = AutoConfigurationPackages.get(beanFactory)
  20.         logger.info("CustomAutoConfig AutoConfiguration Packages: $packages")
  21.         return packages.firstOrNull() ?: "edu.tyut"
  22.     }
  23. }
复制代码
3. 注册自动配置类

在文件resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports下注册:
  1. edu.tyut.config.CustomAutoConfig
复制代码
End, 怎么样是不是非常简单
原理解析

1. 启动类的注解@SpringBootApplication

源码如下:
  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @SpringBootConfiguration
  6. @EnableAutoConfiguration
  7. @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  8.                 @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  9. public @interface SpringBootApplication {
  10. ...
  11. }
复制代码
2. @EnableAutoConfiguration

源码如下:
  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Inherited
  5. @AutoConfigurationPackage
  6. @Import(AutoConfigurationImportSelector.class)
  7. public @interface EnableAutoConfiguration {
  8. ...
  9. }
复制代码
3. AutoConfigurationImportSelector

源码如下:
  1. public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
  2.                 ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
  3.         private final Class<?> autoConfigurationAnnotation;
  4.         AutoConfigurationImportSelector(Class<?> autoConfigurationAnnotation) {
  5.                 this.autoConfigurationAnnotation = (autoConfigurationAnnotation != null) ? autoConfigurationAnnotation
  6.                                 : AutoConfiguration.class;
  7.         }
  8. ...
  9.         protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
  10.                 ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation,
  11.                                 getBeanClassLoader());
  12.                 List<String> configurations = importCandidates.getCandidates();
  13.                 Assert.state(!CollectionUtils.isEmpty(configurations),
  14.                                 "No auto configuration classes found in " + "META-INF/spring/"
  15.                                                 + this.autoConfigurationAnnotation.getName() + ".imports. If you "
  16.                                                 + "are using a custom packaging, make sure that file is correct.");
  17.                 return configurations;
  18.         }
  19. ...
  20. }
复制代码
代码解读
查看该类构造函数可以发现其有一个成员变量autoConfigurationAnnotation,其值为org.springframework.boot.autoconfigure.AutoConfiguration.
getCandidateConfigurations的参数为即为org.springframework.boot.autoconfigure.AutoConfiguration.
4. org.springframework.boot.context.annotation.ImportCandidates

源码如下:
  1. public final class ImportCandidates implements Iterable<String> {
  2. ...
  3.         public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {
  4.                 Assert.notNull(annotation, "'annotation' must not be null");
  5.                 ClassLoader classLoaderToUse = decideClassloader(classLoader);
  6.                 String location = String.format(LOCATION, annotation.getName());
  7.                 Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
  8.                 List<String> importCandidates = new ArrayList<>();
  9.                 while (urls.hasMoreElements()) {
  10.                         URL url = urls.nextElement();
  11.                         importCandidates.addAll(readCandidateConfigurations(url));
  12.                 }
  13.                 return new ImportCandidates(importCandidates);
  14.         }
  15. }
复制代码
代码解读:
找到类路径下所有的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 本文分享结束, 有什么不足还请大家指出

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册