如果你在一个开发共享库的公司工作,或者你在一个开源的或商业的图书馆工作,你可能想开发自己的自动配置。自动配置类可以捆绑在外部的 jar 中,并且仍然由 Spring Boot 来拾取。 自动配置可以与提供自动配置代码的 “starter” 以及你将使用的典型库相关联。我们首先覆盖你需要知道的,以建立你自己的自动配置,然后我们转到创建自定义启动器所需的典型步骤。
在底层,自动配置是用标准
你可以浏览
Spring Boot 检查是否存在发布的 jar 中的 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\ com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
如果你的配置需要以特定的顺序应用,你可以使用
如果你想指定某些不应该有任何直接知识的自动配置,你也可以使用
你几乎总是希望在自动配置类上包含一个或多个
Spring Boot 包含大量的
当放置在 @Configuration public class MyAutoConfiguration { @Bean @ConditionalOnMissingBean public MyService myService() { ... } }
在前面的示例中,如果
当特定资源存在时,
基于SpEL表达式的结果,可以包含@条件语句表达式注释。
自动配置可以能受到多种因素影响:用户配置(
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(UserServiceAutoConfiguration.class));
每个测试都可以使用转轮来表示特定的用例。例如,下面的示例调用用户配置( @Test public void defaultServiceBacksOff() { this.contextRunner.withUserConfiguration(UserConfiguration.class) .run((context) -> { assertThat(context).hasSingleBean(UserService.class); assertThat(context.getBean(UserService.class)).isSameAs( context.getBean(UserConfiguration.class).myUserService()); }); } @Configuration static class UserConfiguration { @Bean public UserService myUserService() { return new UserService("mine"); } }
还可以容易地定制 @Test public void serviceNameCanBeConfigured() { this.contextRunner.withPropertyValues("user.name=test123").run((context) -> { assertThat(context).hasSingleBean(UserService.class); assertThat(context.getBean(UserService.class).getName()).isEqualTo("test123"); }); }
如果你需要测试仅在 Servlet 或 Reactive web 应用程序上下文中运行的自动配置,则分别使用
还可以测试在运行时不存在特定类和/或包时发生的情况。Spring Boot 有一个可以被运行者轻松使用的 @Test public void serviceIsIgnoredIfLibraryIsNotPresent() { this.contextRunner.withClassLoader(new FilteredClassLoader(UserService.class)) .run((context) -> assertThat(context).doesNotHaveBean("userService")); } 一个用于库的完整 Spring Boot 启动器可以包含以下组件:
你应该确保为你的启动器提供一个合适的命名空间。即使使用不同的 Maven
作为经验法则,你应该在启动器之后命名组合模块。例如,假设你正在为 "acme" 创建一个启动器,并且将自动配置模块命名为
此外,如果启动器提供了配置键,则为它们使用唯一的命名空间。特别地,不要在 Spring Boot 使用的命名空间中包括你的键(例如
确保触发元数据生成,以便 IDE 辅助也可用于你的键。你可能需要查看生成的元数据(
Spring Boot 使用注解处理器来收集元数据文件汇总的自动配置条件( <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure-processor</artifactId> <optional>true</optional> </dependency>
使用 Gradle 4.5 及更早版本,依赖关系应该在 dependencies {
compileOnly "org.springframework.boot:spring-boot-autoconfigure-processor"
}
使用 Gradle 4.6 及更新版本,依赖关系应该在 dependencies {
annotationProcessor "org.springframework.boot:spring-boot-autoconfigure-processor"
}
启动器是一个空 jar。它的唯一目的是提供与库一起工作的必要依赖,你可以把它看作是启动必需的自用视图。 不要假设你的启动器添加的项目。如果你自动配置的库通常需要其它启动器,那么也要提及它们。如果可选依赖项的数量很高,则提供适当的默认依赖集可能会很困难,因为你应该避免对常用的库包含不必要的依赖项。换句话说,不应该包含可选的依赖项。
Kotlin 是面向 JVM(和其它平台)的静态类型语言,它允许编写简洁优雅的代码,同时提供与 Java 编写的现有库的互操作性。 Spring Boot 通过支持其它 Spring 项目(如 Spring Framework、Spring Data 和 Reactor)提供 Kotlin 支持。有关的更多详细信息请参阅 Spring Framework Kotlin 支持文档。
从 Spring Boot 和 Kotlin 开始的最简单的方法是遵循这个全面的教程。你可以通过 start.spring.io 创建新的 Kotlin 项目。如果你需要支持,可以自由加入 Kotlin Slack 的 #spring 通道,或者在 Stack Overflow 上使用
Spring Boot 支持 Kotlin 1.2.x。为了使用 Kotlin, 由于默认情况下 Kotlin 类是 final,所以你可能希望配置 kotlin-spring 插件,以便自动打开 Spring 注解类,以便它们可以代理。 Jackson 的 Kotlin 模块是在 Kotlin 中序列化/反序列化 JSON 数据所必需的。它在类路径上找到时自动注册。如果存在 Jackson 和 Kotlin,但 Jackson Kotlin 不存在,则记录警告消息。
Kotlin 的一个关键特征是 null-safety。它在编译时处理 虽然 Java 不允许在其它类型系统中表达 null 安全性,但是 Spring Framework、Spring Data 和 Reactor 现在通过工具友好注解提供 API 的 null 安全性。默认情况下,Kotlin 中使用的 Java API 类型被认为是宽松 null 检查的平台类型。Kotlin 支持 JSR 305 注解与可空性注解相结合为 Kotlin 中的相关 Spring API 提供了 null 安全性。
JSR 305 检查可以通过添加 警告:泛型类型参数、varargs 和数组元素可空性尚未得到支持。参见 SPR-15942 的最新信息。还要注意,Spring Boot 自身的 API 还没有注解。
Spring Boot 提供了一个用 import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication @SpringBootApplication class MyApplication fun main(args: Array<String>) { runApplication<MyApplication>(*args) }
这是 runApplication<MyApplication>(*args) { setBannerMode(OFF) } Kotlin 扩展提供了用附加功能扩展现有类的能力。Spring Boot Kotlin API 利用这些扩展来向现有 API 添加新的 Kotlin 特定的便利。
为了避免将不同版本的 Kotlin 依赖性混合到类路径上,提供了以下 Kotlin 依赖关系的依赖管理:
使用 Maven,Kotlin 版本可以通过
@ConfigurationProperties("example.kotlin") class KotlinExampleProperties { lateinit var name: String lateinit var description: String val myService = MyService() class MyService { lateinit var apiToken: String lateinit var uri: URI } }
虽然可以使用 JUnit 4(
若要使用 JUnit 5,请从
如果你想了解更多有关本节中讨论的类的内容,可以查看 Spring Boot API 文档,或者可以直接浏览源代码。如果你有具体的问题,请看 how-to 部分。 如果你对 Spring Boot 的核心特性感到满意,你可以继续并阅读关于生产就绪的特性。 |