写的比较早,我们每次构建Spring应用,都不想从零开始实现带有“横切关注点”的内容;相反,我们希望一次性实现这些功能,并根据需要将它们包含在我们想要构建的任何应用程序中。
横切关注点
横切关注点:指一些跨越多个模块的行为(从维基百科引入),即可以被多个项目或模块使用的内容,比如一个SDK。
在Spring Boot,用来表示提供这种横切关注点的模块的术语是starter。依靠starter,您可以轻松地使用它的一些功能特性。无论你是否会在工作中打造自己的首发,你都要有打造“首发”的想法。本文将结合Spring Boot官方标准构建一个简单的启动器。
定制启动器在我们进一步了解如何定制启动器之前,为了更好地理解我们在每一步都在做什么以及启动器是如何工作的,我们先从宏观的角度来看一下启动器的结构。
通常一个完整的起动机需要包括以下两个部件:
自动配置模块Starter模块如果你看下面两个组件的解释,有点抽象,你就可以了解了。看完这篇文章,回头看这里,你会豁然开朗。
自动配置模块
自动配置模块是包含自动配置类的Maven或Gradle模块。通过这种方式,我们可以构建能够自动贡献给应用程序上下文的模块,并添加一个特性或提供对外部库的访问。
起动机模块
Spring Boot启动器是一个Maven或Gradle模块,其唯一目的是提供& # 34;开始& # 34;功能所需的所有依赖关系。您可以包括一个或多个自动配置模块依赖项,以及您可能需要的任何其他依赖项。这样,在Spring startup应用程序中,我们只需要添加这个starter依赖项就可以使用它的特性。
Spring官方参考手册建议将自动配置分开,将每个自动配置启动到一个独立的Maven或Gradle模块中,从而将自动配置与依赖管理分开。如果您没有为成千上万的用户构建一个开源库,您也可以将它们合并到一个模块中,如果您不需要分离两个关注点,您可以将自动配置代码和依赖性管理合并到一个模块中。
名字
来自Spring官方的启动器都是用spring-boot-starter启动的,比如:
spring-boot-starter-webspring-boot-starter-AOP如果我们将starter函数的名称定义为acme,那么我们的名称如下:
acme-spring-Boot-starter acme-Spring-Boot-Auto Configure如果在Starter中使用了配置键,还应该注意不要使用Spring Boot使用的命名空 room,比如(server,management,Spring)。
父模块创建
让我们来看看项目的整体结构:一级目录结构:
。├──POM . XML├───ryb-spring-boot-auto configure├───ryb-spring-boot-sample└───ryb-spring-boot-starter二级目录结构:
。├──pom.xml├──rgy b-spring-boot-auto configure│├──pom.xml│└──src├──rgy b-spring-boot-sample│├──POM . XML│└──src└──rgy b-spring-boot-starter├──p om . XML└──src创建一个Maven模块,也就是空之父,主要提供依赖管理,这样子模块就不需要单独维护依赖版本号,从而可以查看POM . XML内容:
& lt依赖关系管理>。& lt依赖关系& gt& lt依赖性& gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gtspring-boot-dependencies/artifact id & gt;& lt版本& gt$ { spring-boot . version } & lt;/version & gt;& lttype & gtpom & lt/type & gt;& lt范围& gt导入& lt/scope & gt;& lt/dependency & gt;& lt/dependencies & gt;& lt!-在此添加其他全局依赖关系管理。默认情况下,子模块不会引入这些依赖关系,所以需要显式指定-& gt;& lt/dependency management & gt;自动配置模块结构
创建一个新类GreetingAutoConfiguration
@ configuration public class greeting auto configuration { @ Bean public greeting service greeting service(greeting properties greeting properties){ return new greeting service(greeting properties . get members());}}我们使用@Configuration注释标签类GreetingAutoConfiguration作为启动器的入口点。这个配置包含了我们提供starter特性所需的所有@Bean定义。在本例中,为了简单起见,我们只将GreetingService Bean添加到应用程序上下文中。
欢迎服务的内容如下:
@ AllArgsConstructorpublic class greeting service { private List & lt;字符串& gtmembers = new ArrayList & lt& gt();public void say hello(){ members . foreach(s-& gt;system . out . println(& # 34;你好& # 34;+s));}}在resources目录下新建一个文件META-INF/spring.factors(如果META-INF目录不存在,需要手动创建),写入文件:
org . spring framework . boot . auto configure . enable auto configuration = \ Top。达亚奇。自动配置。greeting auto configuration Spring将启动其类路径中的所有spring.factoreis文件,并在其中加载声明的配置。当问候自动配置类准备就绪时,我们的Spring Boot启动器将有一个自动激活的入口点。
这里这个& # 34;不完整的启动器& # 34;已经可以用了。但是因为是自动激活的,为了让它灵活,我们需要根据自己的意愿来激活,所以需要条件注释来帮助。
条件配置
向类中添加两个条件注释:
@ Configuration @ conditional property(value = & # 34;rgyb . greeting . enable & # 34;,具有值= & # 34;真& # 34;)@ conditional class(dummy mail . class)public class问候语自动配置{…}通过使用annotation @ conditional属性,我们告诉Spring,只有当属性rgyb.greeting.enable的值设置为true时,GreetingAutoConfiguration(及其声明的所有bean)才会包含在应用程序上下文中。通过使用@ConditionalOnClass注释,我们告诉Spring,只有当类DummyEmail.class存在于类路径中时,才会将GreetingAutoConfiguration(及其声明的所有bean)包含在应用程序上下文中。多个条件为and/ AND,只有满足所有条件时才会加载GreetingAutoConfiguration。
如果不清楚条件注释的用法,可以查看我之前的文章:@条件注释,Spring Boot的灵活配置。
配置属性管理
上面使用了@ConditionalOnProperty注释,实际的starter中可能有很多属性,所以我们需要集中管理这些属性:
@Data@ConfigurationProperties(前缀= & # 34;rgyb.greeting & # 34)public class问候语属性{/* * *问候语属性开关*/boolean enable = false;/* * *需要打招呼的成员列表*/list
& lt依赖性& gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gt弹簧引导配置处理器& lt/artifact id & gt;& lt可选& gttrue & lt/可选& gt& lt/dependency & gt;这样我们mvn编译的时候就会生成一个名为Spring-Configuration-Metadata的文件。JSON,如下所示:
生成的内容用在下面的内容里,看看。
提升开始时间
对于类路径上的每个自动配置类,Spring Boot必须计算@Conditional… condition值,该值用于决定是否加载自动配置及其需要的所有类。根据Spring启动应用程序中启动器的大小和数量,这可能是一个非常昂贵的操作,并且会影响启动时间。为了缩短启动时间,我们需要在pom.xml中添加另一个依赖项:
& lt依赖性& gt& ltgroupId & gtorg . spring framework . boot & lt;/groupId & gt;& ltartifactId & gtspring-boot-自动配置-处理器& lt/artifact id & gt;& lt可选& gttrue & lt/可选& gt& lt/dependency & gt;这个注释将生成一个名为Spring-Autoconfigure-metadata的属性文件。属性,其内容如下:
这样,Spring Boot可以在启动时读取这些元数据,并且可以在不实际检查这些类的情况下过滤掉不符合条件的配置,从而提高启动速度。
至此,自动配置模块已经构建完毕,我们需要继续构建启动模块。
起动机模块结构
启动模块的结构非常简单。你可以把它想象成一个空模块。除了依赖自动配置模块之外,它唯一的功能是提供使用starter特性所需的所有依赖关系,因此我们将以下内容添加到Starter模块的pom.xml文件中:
& lt依赖关系& gt& lt依赖性& gt& ltgroupId & gttop . day arch . learning & lt。/groupId & gt;& ltartifactId & gtrgy b-spring-boot-auto configure & lt;/artifact id & gt;& lt版本& gt1.0.0 .发布& lt/version & gt;& lt/dependency & gt;& lt!-在此添加其他必要的依赖项,以确保启动程序可用-& gt;& lt/dependencies & gt;同样,在resources目录下创建一个新文件META-INF/spring.providers,内容如下:
providers:rgy b-spring-boot-auto configure这个文件的主要作用是解释starter模块的依赖信息。用逗号分隔多个依赖关系即可。该文件不会影响starter的使用,并且是可选的。
启动模块就这么简单。将这两个模块安装到本地Maven存储库中,然后我们将创建一个示例模块来介绍这个starter依赖项,它将从本地Maven存储库中提取。
创建示例模块我们可以通过Spring Initializr正常初始化一个Spring Boot项目(RYB-Spring-Boot-Sample),引入我们刚刚创建的starter依赖项,在sample pom.xml中添加依赖项:
& lt依赖性& gt& ltgroupId & gttop . day arch . learning & lt。/groupId & gt;& ltartifactId & gtrgy b-spring-boot-starter & lt;/artifact id & gt;& lt版本& gt1.0.0 .发布& lt/version & gt;& lt/dependency & gt;接下来,配置application.yml属性。
RYB:问候:启用:真实成员:-李磊-韩梅梅当我们配置YAML时,会出现如下提示,会更友好。当然,为了规范起见,属性描述最好用英文描述,这里用中文描述来说明问题:
编写测试类
我们编写测试用例:
@ Autowired(required = false)private greeting service greeting service;@ test public void test greeting(){ greeting service . say hello();测试结果如下:
你好李磊你好韩梅梅总结,完整的首发开发到此结束。希望大家能了解它的构建流程,目录结构,命名标准,以便大家在有相应的业务需求时,开发自己的启动器,供他人应用。
启动器开发完成后,其他人可以手动添加依赖项来引入启动器的相关功能。那么如何才能像Spring Initializer一样通过下拉菜单选择我们的starter,从而直接初始化整个项目呢?在下面的文章中,我们将模仿Spring初始化器来定制我们自己的初始化器。
知识点描述
依赖选项
为什么自动配置模块的依赖项都是可选的=真?这就涉及到Maven传递依赖的问题。详见Maven对及物性依赖的透彻理解。
春天.工厂
Spring Boot是如何加载这个文件并找到我们的配置类的?下图是Spring Boot应用程序启动的调用堆栈的一部分,我添加了断点:
打开SpringFactoriesLoader类,这就是您看到的内容:
这两张图应该足够说明问题了。它们是SPI的一种加载方法。更多详情请自行了解。
实际案例
建议查一下mybatis-spring-boot-starter的非官方案例,从中我们:
模仿它的目录结构、设计概念和编码规范。
主题测试文章,只做测试使用。发布者:rekoe,转转请注明出处:https://www.mulub.com/8634.html