SpringBoot3 自定义 Starter
SpringBoot3 自定义 StarterSpringBoo3 最简单自定义 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 = )
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.CustomAutoConfigEnd, 怎么样是不是非常简单
原理解析
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 本文分享结束, 有什么不足还请大家指出
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]