Hello 👋
I face a case where I want to "enhance" the DSLContext provided by JOOQ, to leverage MetricsDSLContext features of Micrometer.
However, such "decorator" is complicated to configure in Spring Boot, due to the restriction on depdendency cycles.
I wanted to do something like this, but it fails:
@Bean
fun dslContext(configuration: org.jooq.Configuration, registry: MeterRegistry): MetricsDSLContext {
return MetricsDSLContext.withMetrics(configuration.dsl(), registry, Tags.of("query", "jooq") )
}
And it's not possible to only inject the org.jooq.Configuration bean, because it's created only if there is no bean of type DSLContext defined… and I define one 🤷
I had to do that in my code to have something ok:
@Configuration
@EnableConfigurationProperties(JooqProperties::class)
class JooqConfig {
@Bean
fun jooqConfiguration(
properties: JooqProperties,
connectionProvider: ConnectionProvider?,
dataSource: DataSource?,
transactionProvider: ObjectProvider<TransactionProvider?>,
executeListenerProviders: ObjectProvider<ExecuteListenerProvider?>,
configurationCustomizers: ObjectProvider<DefaultConfigurationCustomizer>,
): DefaultConfiguration {
return DefaultConfiguration().apply {
set(properties.determineSqlDialect(dataSource))
set(connectionProvider)
transactionProvider.ifAvailable(this::set)
configurationCustomizers.orderedStream().forEach { it.customize(this) }
set(*executeListenerProviders.orderedStream().collect(Collectors.toList()).toTypedArray())
}
}
@Bean
fun dslContext(configuration: org.jooq.Configuration, registry: MeterRegistry): MetricsDSLContext {
return MetricsDSLContext.withMetrics(configuration.dsl(), registry, Tags.of("query", "jooq") )
}
}
The @EnableConfigurationProperties(JooqProperties::class) and fun jooqConfiguration comes from the Spring code base #copypaste
This limitation is the result of the DslContextConfiguration class, it hosts both the DSLContext and Configuration beans.
Would it be possible to split it to allow users to use the predefined Configuration generated by Spring Boot without the DSLContext?
If it's ok for you, I'll be glad to open a PR, but I wanted to present the case before doing an implementation.
Thank you!
Comment From: wilkinsona
This sort of decoration of a bean is typically a good use case for a bean post-processor. You could try something like this:
@Bean
static BeanPostProcessor jooqMetrics(ObjectProvider<MeterRegistry> meterRegistry) {
return new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DSLContext dslContext) {
return new MetricsDSLContext(dslContext, meterRegistry.getObject(), Tags.of("query", "jooq"));
}
return bean;
}
};
}
Comment From: davinkevin
I agree, but I reported this issue because I had the same problem before introduction of r2dbc in spring-boot using jooq. In that context, the bean postprocessor was not a possible solution.
So, would you like a PR to split org.jooq.Configuration and DSLContext auto configuration, so we leverage the first even if the second is under configuration?