使用 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 的依赖。顺序如下:
dataSource
豆子
flyway
豆子
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 在创建会话工厂之前再次可用。这解决了问题。
我正在使用 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 的依赖。顺序如下:
dataSource
豆子flyway
豆子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:
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 在创建会话工厂之前再次可用。这解决了问题。