如何编写在 Spring 配置生命周期中不创建要运行的 bean 的启动逻辑?

问题描述 投票:0回答:3

除了使用 @configuration 和 @bean 配置的传统 bean 之外,我们的代码中还有一些必须在启动时完成的启动逻辑,例如在数据库上运行 liquibase、将配置数据从文件加载到数据库以及执行一些理智操作测试。 所有这些都与随后自动装配的 Bean 无关,更改是通过数据库而不是 spring 保存的。 然而,还有大量工作要做。 其中大部分还依赖于早期步骤的完成和/或服务的自动连接。

在 Spring 环境中执行此操作的最佳方法是什么? 我知道我们可以使用一个 ApplicationContextAware 来启动这个逻辑,但由于一些原因,它似乎不合适

  1. 它将运行应用程序上下文刷新,而不仅仅是在启动时
  2. 这将允许只运行一个类,我更愿意能够像 @configuration 那样编写逻辑,我可以在其中添加一个新组件并让它在适当的地方运行
  3. 至少在一种情况下,我们有一个 bean,在完成一些数据库配置之前我们无法正确配置,这意味着我们希望此配置逻辑在 spring 启动的中间运行,而不是在最后运行。

目前我们采用的方法是 @Configuration 类,没有 @bean 方法,而是使用 afterPropertiesSet() 来运行数据库配置文件,该文件在大型配置方法中顺序执行每个数据库配置阶段。 这确实工作得很好,但感觉它破坏了 @configuration 的预期用途,即显式用于为以后的自动装配创建 @bean 定义。

spring 是否提供了更好的方法来将非 bean 配置添加到其配置/自动装配阶段的中间,或者这是可用的最佳方法?

回答评论中的问题,这是一个使用 spring-mvc 的 Restful Web 应用程序。 当网络服务器启动时,这是一场战争。

java spring spring-mvc
3个回答
2
投票

我有类似的需求,我想在服务器启动时从数据库中获取记录并将其放入缓存中,我通过在服务类中编写一个方法并将其注释为

@PostConstruct
来实现它。将会发生的情况是,一旦 Bean 创建完成,该方法将执行,并且仅在 Bean 创建后或服务器启动期间执行一次。

这非常简单,因为您不需要编写单独的类,只需在控制器/服务类中创建一个附加方法即可完成。


1
投票

您可以使用 Interface ApplicationContextInitializer 来满足此需求

来自 Spring 文档

公共接口ApplicationContextInitializer

用于初始化Spring的回调接口 刷新之前的 ConfigurableApplicationContext。

通常在需要某些功能的 Web 应用程序中使用 应用程序上下文的编程初始化。例如, 注册财产来源或激活配置文件 上下文的环境。请参阅 ContextLoader 和 FrameworkServlet 支持 用于声明“contextInitializerClasses”上下文参数和 分别是 init-param。


0
投票

是的,当然可以。

如果您有带有

@Configuration
注释的 Config 类,您可以将任何初始化逻辑放入用适当的
@PostConstruct
注释注释的方法中。

甚至更多:创建具有 void 返回类型的方法并将逻辑放在那里。 例如:

@Autowired
void init(@Value("${some.value}") String someValue, Bean someBean) {
   // some logic goes here
}
© www.soinside.com 2019 - 2024. All rights reserved.