Spring Modulith Runtime Support

前几章所述的功能都使用了应用程序模块的排列,用于用于验证和文档目的的测试场景或通用支持功能,这些功能有助于将模块松散耦合,但不会直接与应用程序模块结构配合使用。本节我们将介绍 Spring Modulith 对应用程序运行时模块初始化的支持。

The functionality described in previous chapters have all used the application module arrangement in either testing scenarios for verification and documentation purposes or were general support functionality that help to loosely couple modules but did not work with the application module structure directly. In this section we are going to describe Spring Modulith’s support for module initialization at application runtime.

Setting up Runtime Support for Application Modules

若要为 Spring Modulith 启用运行时支持, 请确保在你的项目中包含`spring-modulith-runtime` JAR。

To enable the runtime support for Spring Modulith, make sure you include the spring-modulith-runtime JAR in your project.

  • Maven

  • Gradle

<dependency>
  <groupId>org.springframework.modulith</groupId>
  <artifactId>spring-modulith-runtime</artifactId>
  <scope>runtime</scope>
</dependency>
dependencies {
  runtimeOnly 'org.springframework.modulith:spring-modulith-runtime'
}

值得注意的是,使用 Spring Modulith 的运行时支持意味着您要在应用程序中包含 ArchUnit 和必需的 JGraphT (用于对应用程序模块进行拓扑排序)库。

It’s worth noting that using the runtime support of Spring Modulith will mean that you include both ArchUnit and the JGraphT (required to topologically sort application modules) library in your application.

添加此 JAR 将导致 Spring Boot 自动配置运行,该配置将以下组件注册到你的应用程序中:

Adding this JAR will cause Spring Boot auto-configuration to run that registers the following components in your application:

  • An ApplicationModulesRuntime that allows to access the ApplicationModules.

  • A SpringBootApplicationRuntime to back the former bean to detect the main application class.

  • An event listener for ApplicationStartedEvents that will invoke ApplicationModuleInitializer beans defined in the application context.

Application Module Initializers

在使用应用程序模块时,在应用程序启动时需要执行特定于单个模块的一些代码非常常见。这意味着该代码的执行顺序需要遵循应用程序模块的依赖结构。如果模块 B 依赖于模块 A,则即使初始化程序不直接依赖于另一个初始化程序,模块 A 的初始化代码也必须在 B 的初始化代码之前运行。

When working with application modules, it is pretty common to need to execute some code specific to an individual module on application startup. This means that the execution order of that code needs to follow the dependency structure of the application modules. If a module B depends on module A, the initialization code of A has to run before the one for B, even if the initializers do not directly depend on another.

hide empty members

package org.springframework.modulith { interface ApplicationModuleInitializer }

package com.acme.moduleA { class InitializerA implements ApplicationModuleInitializer

  class ComponentA
}

package com.acme.moduleB {

class ComponentB
  class InitializerB implements ApplicationModuleInitializer
}

ComponentB -→ ComponentA

虽然开发人员当然可以通过 Spring 的标准`@Order`注解或`Ordered`接口定义执行顺序,但 Spring Modulith 提供了一个`ApplicationModuleInitializer`接口,用于在应用程序启动时运行 Bean。这些 Bean 的执行顺序将自动遵循应用程序模块的依赖结构。

While developers could of course define the execution order via Spring’s standard @Order annotation or Ordered interface, Spring Modulith provides an ApplicationModuleInitializer interface for beans to be run on application startup. The execution order of those beans will automatically follow the application module dependency structure.

  • Java

  • Kotlin

@Component
class MyInitializer implements ApplicationModuleInitializer {

  @Override
  public void initialize() {
    // Initialization code goes here
  }
}
@Component
class MyInitializer : ApplicationModuleInitializer {


  override fun initialize() {
    // Initialization code goes here
  }
}

请注意,只有当 spring-modulith-runtime JAR 在类路径中时, ApplicationModuleInitializer Bean 才会被调用(参见 Setting up Runtime Support for Application Modules),因为它会提取对根据应用程序模块结构对初始化器进行拓扑排序所需的依赖项。

Note, that the ApplicationModuleInitializer beans will only be invoked if the spring-modulith-runtime JAR is on the classpath (see Setting up Runtime Support for Application Modules) as that pulls in the dependencies that are needed to topologically sort the initializers according to the application module structure.