使用Kotlin Arrow自定义Spring Data存储库

21-10-28 banq

Spring Data 提供了一个开箱即用的存储库实现。当这还不够时,其灵活的设计使其可以在不同的抽象级别扩展代码。

这篇文章展示了如何用我们自己的库替换默认的基础库,它在函数签名中使用Kotlin Arrow类型。

这篇文章的完整源代码可以在Github 上以 Maven 格式找到。

函数式编程正变得越来越流行。Spring 为Kotlin 语言提供了几个DSL。例如,Beans DSLRoutes DSL为 Spring 配置提供了更多功能的方法。在类型方面,Vavr(以前是 Javaslang)在 Java 中非常流行,而 Kotlin 有Arrow

下面是非常标准的起步架构

  1. 具有两个GET映射的REST 控制器
  2. Spring Data JDBC 存储库接口

因为它是标准的,Spring 处理了很多管道,我们不需要编写很多代码。使用 Kotlin,它更加简洁:

class Person(@Id val id: Long, var name: String, var birthdate: LocalDate?)

interface PersonRepository : CrudRepository<Person, Long>

@RestController
class PersonController(private val repository: PersonRepository) {

    @GetMapping
    fun getAll(): Iterable<Person> = repository.findAll()

    @GetMapping("/{id}")
    fun getOne(@PathVariable id: Long) = repository.findById(id)
}

@SpringBootApplication
class SpringDataArrowApplication

fun main(args: Array<String>) {
    runApplication<SpringDataArrowApplication>(*args)
}

 

Arrow 带有四个不同的组件:

  1. Core
  2. FX:KotlinX 协程的功能效果框架伴侣
  3. Optics:对不可变数据的深度访问和转换
  4. Meta:用于 Kotlin 编译器插件的元编程库

 

更改Spring Data默认基础存储库

为了克服这个限制,我们可以利用另一个扩展点:更改默认的Spring Data基本存储库。

Spring Data 应用程序定义了接口,但实现需要来自某个地方。该框架默认提供一个,但可以用我们自己的来切换它。

下面是类图的概述:

详细的流程非常复杂:重要的部分是SimpleJdbcRepository类。Spring Data 将通过JdbcRepositoryFactoryBeanbean找到该类,创建它的一个新实例并在上下文中注册该实例。

让我们创建一个使用Either以下内容的基本存储库:

@NoRepositoryBean
interface ArrowRepository<T, ID> : Repository<T, ID> {              
    fun findById(id: Long): Either<Unit, T>                          
    fun findAll(): Iterable<T>                                       
}

class SimpleArrowRepository<T, ID>(                                 
    private val ops: JdbcAggregateOperations,
    private val entity: PersistentEntity<T, *>
) : ArrowRepository<T, ID> {

    override fun findById(id: Long) = Either.fromNullable(
        ops.findById(id, entity.type)                                
    )

    override fun findAll(): Iterable<T> = ops.findAll(entity.type)
}

我们需要注释主应用程序类@EnableJdbcRepositories并配置后者切换到这个基类。

@SpringBootApplication
@EnableJdbcRepositories(repositoryBaseClass = SimpleArrowRepository::class)
class SpringDataArrowApplication

为了简化客户端代码的使用,我们可以创建一个覆盖默认值的注释:

@EnableJdbcRepositories(repositoryBaseClass = SimpleArrowRepository::class)
annotation class EnableArrowRepositories

现在,用法很简单:

@SpringBootApplication
@EnableArrowRepositories
class SpringDataArrowApplication

此时,我们可以将 Arrow 存储库代码移动到其项目中,并将其分发给其他“客户端”项目使用。

 

1
猜你喜欢