如何为@query设置spel contextprovider

tcomlyy6  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(381)

如何设置上下文提供程序以使我的spel扩展在 @Query("...") ?
我们在postgres中使用r2dbc。
据我所知,我需要注册一个 ReactiveExtensionAwareQueryMethodEvaluationContextProvider 但我找不到任何关于如何做到这一点的文件。有没有一个特定的豆子或者 @Configuration 用它吗?
我找到了这个单元测试。它是monogo而不是r2dbc,但我认为这是相同的原则-但是因为它是一个单元测试,所以它没有显示如何在我的普通代码中设置上下文。
试图这样实现它并不能提供 my() spel中的方法

  1. @Configuration
  2. class MySpELExtensionConf {
  3. @Bean
  4. fun mySpELExtension() : ReactiveEvaluationContextExtension {
  5. return ReactiveSpelExtension()
  6. }
  7. class ReactiveSpelExtension : ReactiveEvaluationContextExtension {
  8. override fun getExtension(): Mono<out EvaluationContextExtension> {
  9. return Mono.just(SpelExtension.INSTANCE)
  10. }
  11. override fun getExtensionId(): String {
  12. ReactiveQueryMethodEvaluationContextProvider.DEFAULT
  13. return "mySpELExtension"
  14. }
  15. }
  16. enum class SpelExtension : EvaluationContextExtension {
  17. INSTANCE;
  18. override fun getRootObject(): Any? {
  19. return this
  20. }
  21. override fun getExtensionId(): String {
  22. return "mySpELExtension"
  23. }
  24. fun my(): String {
  25. return "x"
  26. }
  27. }
  28. }

我现在看到 mySpELExtension 在应用程序上下文中,但是使用 my() a中的方法 @Query 不可能:

  1. interface MyRepository : ReactiveCrudRepository<MyEntity, Long> {
  2. @Query("""
  3. ...
  4. :#{my()}
  5. ...
  6. """)
  7. fun findByMyQuery() : Flux<MyEntity>
  8. }

结果

  1. EL1004E: Method call: Method my() cannot be found on type java.lang.Object[]
332nm8kg

332nm8kg1#

我利用 PostBeanProcessor .

  1. @Configuration
  2. class MySpELExtensionConf {
  3. companion object {
  4. // list of provided extensions
  5. val contextProviderWithExtensions =
  6. ReactiveExtensionAwareQueryMethodEvaluationContextProvider(listOf(ReactiveSpelExtension()))
  7. }
  8. /**
  9. * Registers the customizer to the context to make spring aware of the bean post processor.
  10. */
  11. @Bean
  12. fun spELContextInRepositoriesCustomizer(): AddExtensionsToRepositoryBeanPostProcessor {
  13. return AddExtensionsToRepositoryBeanPostProcessor()
  14. }
  15. /**
  16. * Sets the [contextProviderWithExtensions] for SpEL in the [R2dbcRepositoryFactoryBean]s which makes the extensions
  17. * usable in `@Query(...)` methods.
  18. */
  19. class AddExtensionsToRepositoryBeanPostProcessor : BeanPostProcessor {
  20. override fun postProcessBeforeInitialization(bean: Any, beanName: String): Any {
  21. if (bean is R2dbcRepositoryFactoryBean<*, *, *>) {
  22. bean.addRepositoryFactoryCustomizer { it.setEvaluationContextProvider(contextProviderWithExtensions) }
  23. }
  24. return bean
  25. }
  26. }
  27. // ... extension implementation as in question ...
  28. }

请注意,自定义 R2dbcRepositoryFactoryBean 为…工作 CoroutineCrudRepository 而且您可能需要根据所使用的存储库定制不同的工厂bean。

展开查看全部

相关问题