除了使用@configuration和@bean配置的传统bean之外,我们的代码中还有一些启动逻辑,这些逻辑必须在启动时完成,比如在数据库上运行liquibase,将配置数据从文件加载到数据库,以及执行一些完整性测试。所有这些都与Bean无关,Bean将在之后自动连接,更改将通过数据库持久化,而不是通过spring。然而,还有很多工作要做。这在很大程度上也依赖于之前完成的步骤和/或自动连接的服务。
在spring上下文中做到这一点的最佳方法是什么?我知道有一个ApplicationContextAware,我们可以用它来启动这个逻辑,但它似乎不合适,因为几个原因
- 它将运行一个应用程序上下文刷新,而不仅仅是在启动
- 这将允许只运行一个类,我更喜欢能够编写逻辑的方式,我们做@配置,我可以扔在一个新的组件,并让它在适当的地方运行
- 在至少一种情况下,我们有一个bean,我们不能正确配置,直到一些数据库配置完成,这意味着我们希望这个配置逻辑运行在春季启动的中间,而不是在最后。
目前我们使用的方法是@Configuration类,它没有@bean方法,而是使用afterPropertiesSet()来运行数据库配置文件,该文件在一个大的configure方法中依次遍历每个数据库配置阶段。这确实工作得很好,但感觉它破坏了@configuration的预期用途,即显式地使用@configuration为以后的自动装配创建@bean定义。
spring是否提供了一种更好的方法,能够将非bean配置添加到它的配置/自动装配阶段的中间,或者这是可用的最佳方法?
为了回答评论中的问题,这是一个使用spring-mvc的restful web应用程序。当网络服务器启动时,战争就开始了。
我有类似的要求,我想从DB中获取记录,并在我的服务器启动时将其放入我的缓存,我通过在我的服务类中编写方法并将其注释为@PostConstruct
来实现它。将会发生的是,一旦Bean创建完成,这个方法将执行,它只会在Bean创建后或服务器启动期间执行一次。
这是非常简单的,因为你不需要编写一个单独的类,你可以简单地通过在你的控制器/服务类中创建一个额外的方法来实现。
你可以使用Interface ApplicationContextInitializer来满足这个需求
From Spring Docs
公共接口ApplicationContextInitializer
初始化Spring的回调接口
通常用于需要一些参数的web应用程序应用程序上下文的程序化初始化。例如,注册属性源或激活配置文件上下文环境。参见ContextLoader和FrameworkServlet支持用于声明"contextInitializerClasses"上下文参数和分别初始化。
当然可以。
如果你有用@Configration
注释的配置类,你可以把任何初始化逻辑放入用适当的@PostConstruct
注释的方法中。
或者更多:创建void返回类型的方法,并把你的逻辑放在那里。例如:
@Autowire
void init() {
// some logic goes here
}