Spring 引导,Maven,禁用派生项目中的特定 RestController
Spring Boot, Maven, disable specific RestController in the derived project
在我的 Maven Spring Boot 2 项目中,我有一个名为 api1
的 Maven 模块。我在那里声明了一些 @RestController
。
为了扩展 api1
模块的逻辑,我实现了另一个名为 api2
的 Maven 模块,并将 api1
作为 Maven 依赖项放置在那里。
现在 api1
项目中的所有 @RestController
都在 api2
中初始化,因为它们都存在于 api2
类路径中。
如何禁用api2
项目中的某个@RestController
?
我认为这里要理解的关键事实是 Spring 仅在 runtime 工作,而 maven 在 build 中很重要时间.
所以 Maven 看到 api2 依赖于 api1,所以它知道这两个模块都必须包含在工件中(在 spring 的情况下,它是一个包含所有模块的大罐子)。
现在,当 spring 启动时 - "takes for granted" 所有模块都可以访问,并且根据 spring 配置它只定义要加载和处理的 bean,所有其余控制器都是当然在这些豆子中。
所以我假设,您不介意在工件(和类路径)中有两个模块。
在这种情况下,您根本不应该接触 Maven 部分,但是当 spring 启动应用程序启动时,它必须 "instructed" 以某种方式必须排除一些其余控制器。重点是不应该在模块方面("hey, spring, this controller belongs to module api2, so it has to be excluded"),而是在业务方面"jargon"。例如,api1 包含所有 "admin" 功能,api2 包含所有 "applicative" 内容。因此,如果您使用 Java 配置,例如,您可以执行以下操作:
内部模块 api1:
@Configuration
@ConditionalOnProperty(name = "admin.enabled", havingValue=true)
public class AdminControllersConfiguration {
@Bean
public AdminControllerFromModuleApi1 adminController() {
return new AdminControllerFromModuleApi1();
}
}
}
在模块 api2 中,您只需以类似的方式定义其余控制器,但没有“@ConditionalOnProperty”注释。
这个注解的作用是它允许 "switch off" bean 或整个配置,就像我的示例中那样。
因此,当您启动 api2 时,您只需在 "application.properties" 或以下内容中定义:
admin.enabled=false
并且您的控制器不会被 spring "deployed" 尽管实际上文件肯定在类路径中。
当然,由于spring允许不同类型的配置,这种方法可能不适用于您的项目,但思路还是一样的。
您可以尝试使用 Spring 中的 Condition 接口,该接口支持基于某些 condition/expression.
的 bean 的条件 enable/disable
如下所示:
@RestController
@ConditionalOnExpression("${api1.controller.enabled:false}")
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class Api1Controller {
@RequestMapping(value = "/greeting")
public ResponseEntity<String> greeting() {
return new ResponseEntity<>("Hello world", HttpStatus.OK);
}
}
您必须通过某种方式设置条件表达式(环境变量/属性 键)。检查 this for some reference. Condition docs 可以指导您了解更多详细信息。
在我的 Maven Spring Boot 2 项目中,我有一个名为 api1
的 Maven 模块。我在那里声明了一些 @RestController
。
为了扩展 api1
模块的逻辑,我实现了另一个名为 api2
的 Maven 模块,并将 api1
作为 Maven 依赖项放置在那里。
现在 api1
项目中的所有 @RestController
都在 api2
中初始化,因为它们都存在于 api2
类路径中。
如何禁用api2
项目中的某个@RestController
?
我认为这里要理解的关键事实是 Spring 仅在 runtime 工作,而 maven 在 build 中很重要时间.
所以 Maven 看到 api2 依赖于 api1,所以它知道这两个模块都必须包含在工件中(在 spring 的情况下,它是一个包含所有模块的大罐子)。
现在,当 spring 启动时 - "takes for granted" 所有模块都可以访问,并且根据 spring 配置它只定义要加载和处理的 bean,所有其余控制器都是当然在这些豆子中。
所以我假设,您不介意在工件(和类路径)中有两个模块。
在这种情况下,您根本不应该接触 Maven 部分,但是当 spring 启动应用程序启动时,它必须 "instructed" 以某种方式必须排除一些其余控制器。重点是不应该在模块方面("hey, spring, this controller belongs to module api2, so it has to be excluded"),而是在业务方面"jargon"。例如,api1 包含所有 "admin" 功能,api2 包含所有 "applicative" 内容。因此,如果您使用 Java 配置,例如,您可以执行以下操作:
内部模块 api1:
@Configuration
@ConditionalOnProperty(name = "admin.enabled", havingValue=true)
public class AdminControllersConfiguration {
@Bean
public AdminControllerFromModuleApi1 adminController() {
return new AdminControllerFromModuleApi1();
}
}
}
在模块 api2 中,您只需以类似的方式定义其余控制器,但没有“@ConditionalOnProperty”注释。
这个注解的作用是它允许 "switch off" bean 或整个配置,就像我的示例中那样。
因此,当您启动 api2 时,您只需在 "application.properties" 或以下内容中定义:
admin.enabled=false
并且您的控制器不会被 spring "deployed" 尽管实际上文件肯定在类路径中。
当然,由于spring允许不同类型的配置,这种方法可能不适用于您的项目,但思路还是一样的。
您可以尝试使用 Spring 中的 Condition 接口,该接口支持基于某些 condition/expression.
的 bean 的条件 enable/disable如下所示:
@RestController
@ConditionalOnExpression("${api1.controller.enabled:false}")
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class Api1Controller {
@RequestMapping(value = "/greeting")
public ResponseEntity<String> greeting() {
return new ResponseEntity<>("Hello world", HttpStatus.OK);
}
}
您必须通过某种方式设置条件表达式(环境变量/属性 键)。检查 this for some reference. Condition docs 可以指导您了解更多详细信息。