使用 GORM 6 确定 Grails 3.3 中的 Springs bean 实例化顺序。1.x

Determine Springs bean instantiation order in Grails 3.3 with GORM 6.1.x

我正在使用 Grails 3.3 应用程序,它在后台使用 GORM 6.1.6.RELEASE、Spring-Boot 1.5.4.RELEASE 和 Spring Core 4.3.9.RELEASE。我正在尝试声明一个 Spring bean,它在 Hibernate 开始验证底层数据库模式之前被初始化。

这是我喜欢做的事情。我想将我的 Flyway 注册为 Spring bean 并将 dataSource bean 注入其中。为了在 Hibernate 开始验证当前数据库模式之前让 Flyway 运行,我将我的 flyway bean 添加为对 sessionFactory bean 的依赖。顺序如下:

  1. dataSource豆子
  2. flyway豆子
  3. hiberateDatastore豆子

GORM 6.1 使用 org.grails.orm.hibernate.HibernateDatastore 作为 Spring bean 来初始化 Hibernate ORM 和数据库。 sessionFactory bean 将 hibernateDatastore#getSessionFactory 声明为工厂 class。 因此 hibernateDatastore 总是首先创建。

Grails 3.3 中创建自定义 Spring bean 的方法是什么,它必须 运行 在连接到数据库之后但在 Hibernate 东西初始化之前?

在以前的 Grails 版本中 3.x 可以像这样在 resources.groovy 中声明它。

beans = {

    if (Environment.current == Environment.PRODUCTION) {
        flyway(Flyway) { bean ->
            bean.initMethod = 'migrate'
            dataSource = ref('dataSource')
            locations = 'classpath:db/h2'
            baselineOnMigrate = true
        }

        BeanDefinition sessionFactoryBeanDef = getBeanDefinition('hibernateDatastore')

        if (sessionFactoryBeanDef) {
            def dependsOnList = ['flyway'] as Set
            if (sessionFactoryBeanDef.dependsOn?.length > 0) {
                dependsOnList.addAll(sessionFactoryBeanDef.dependsOn)
            }
            sessionFactoryBeanDef.dependsOn = dependsOnList as String[]
        }
    }
}

我不认为 Spring 提供了 'bean instantion tree' 的可视化,但是您可以将 org.springframework.beans.factory.support.DefaultListableBeanFactory 的日志级别设置为 DEBUG 并且您将获得输出像这样:

Creating shared instance of singleton bean '...fully qualified class name...'

Returning cached instance of singleton bean '...fully qualified class name...'

您可以查看来自 Hibernate 命名空间的 bean 的日志输出。

我假设您将使用结果来声明 DependsOn 关系,因此为了完整起见,它看起来像:

   @Bean 
   public SomeHibernateClass createHibernate() {
       ...
   }

   @Bean
   @DependsOn("createHibernate")
   public MyClass createMine() {
       ...
   }

Grails 3.3.0 改变了 dataSource bean 创建的机制。相关 issue:

中所述的 Grails 项目负责人

Previous versions of Grails created the dataSource bean separately from the session factory. We would need to restore this behaviour I guess so the dataSource can be referenced without triggering the creation of the sessionFactory

升级到 Grails 3.3.1 后,dataSource bean 在创建会话工厂之前再次可用。这解决了问题。