LoginSignup
5
2

More than 5 years have passed since last update.

Spring Boot2.0 KotlinでSpring Data Redisを使ってみたけど、けど

Posted at

Kotlinはじめましたが、微妙なところではまります。
動きはしたのですが謎なところが多かったです。

とりあえず、軽く説明をします。
Apiを叩くとredisに保存、読み取りするだけのapiを作ります。

ソースはこちら
GitHub spring boot 2.0
GitHub spring boot 1.5

実装

gradle

build.gradle
buildscript {
    ext {
        kotlinVersion = '1.2.20'
        springBootVersion = '2.0.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
        classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
    }
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}
compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ["-Xjsr305=strict"]
        jvmTarget = "1.8"
    }
}

repositories {
    mavenCentral()
}

configurations {
    providedRuntime
}

dependencies {
    compile('org.springframework.boot:spring-boot-starter-web')
    compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    compile("org.jetbrains.kotlin:kotlin-reflect")
    providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
    testCompile('org.springframework.boot:spring-boot-starter-test')

    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.4")
    compile("org.apache.commons:commons-pool2:2.5.0")
    compile("redis.clients:jedis:2.9.0")
}

1つ目の謎です。
spring-boot 1.5の時に追加したコンポーネントはspring-boot-starter-data-redis, jackson-module-kotlinだけでしたが、2.0の時はさらにcommons-pool2, jedisが必要でした。
spring-boot-starter-data-redisにcommons-pool2, jedisが依存していてもよさそうです。。。

Kotlin

SampleController.kt
package com.example

import com.example.service.SampleService
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController

@RestController
class SampleController(
        val sampleService: SampleService
) {
    @RequestMapping(value = ["/sample-redis"], method = [RequestMethod.GET])
    fun sampleReids(): SampleDto? {
        return sampleService.getSampleDto();
    }

    @RequestMapping(value = ["/sample-redis2"], method = [RequestMethod.GET])
    fun sampleReids2(): SampleDto? {
        return sampleService.getSampleDto2();
    }
}
SampleDto.kt
package com.example

import java.io.Serializable

class SampleDto(val id:Int, val name:String):Serializable
SampleConfiguration.kt
package com.example

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer

@Configuration
class SampleConfiguration {
    @Bean
    fun jedisConnectionFactory(): JedisConnectionFactory {
        return JedisConnectionFactory()
    }

    @Bean
    fun redisTemplate(): RedisTemplate<String, SampleDto> {
        val template  = RedisTemplate<String, SampleDto>()
        template.setConnectionFactory(jedisConnectionFactory())
        template.keySerializer = StringRedisSerializer()

        val jackson2JsonRedisSerializer = Jackson2JsonRedisSerializer(SampleDto::class.java)
        val om = jacksonObjectMapper()
        jackson2JsonRedisSerializer.setObjectMapper(om)
        template.valueSerializer = jackson2JsonRedisSerializer

        return template;
    }

    @Bean
    fun redisTemplate2(): RedisTemplate<String, String> {
        val template  = RedisTemplate<String, String>()
        template.setConnectionFactory(jedisConnectionFactory())
        template.keySerializer = StringRedisSerializer()
        template.valueSerializer = StringRedisSerializer()
        return template;
    }
}

2つ目の謎です。
connectionFactoryを設定する時の実装が1.5と2.0で違っていました。

Kotlin:spring-boot 1.5
template.connectionFactory = jedisConnectionFactory()

Kotlin:spring-boot 2.0
template.setConnectionFactory(jedisConnectionFactory())

本当は = で設定できるのですかね?

KotlinではJavaの時とは違い Jackson2JsonRedisSerializerを直接設定しても使えなかったので、作成した後にjacksonObjectMapperを設定しました。

redisTemplateの型パラメータを使ってSampleDtoをAnyにしたかったのですが、うまくいきませんでした。
たぶんできるとおもうんだけど。。。
なので、ServiceでredisTemplate2でjson変換をしてConfigurationで文字列を保存するようにしました。

SampleService.kt
package com.example.service

import com.example.SampleDto

interface SampleService {
    fun getSampleDto(): SampleDto?
    fun getSampleDto2(): SampleDto?
}
SampleServiceImpl.kt
package com.example.service

import com.example.SampleDto
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.stereotype.Service

@Service
class SampleServiceImpl(
        val redisTemplate:RedisTemplate<String, SampleDto>,
        val redisTemplate2:RedisTemplate<String, String>
):SampleService {
    override fun getSampleDto():SampleDto? {
        redisTemplate.opsForValue().set("test_dto", SampleDto(1, "aab"))
        return redisTemplate.opsForValue().get("test_dto")
    }

    override fun getSampleDto2():SampleDto? {
        val sampleDto = SampleDto(1, "aac")

        val om = jacksonObjectMapper()

        var jsonStr = om.writeValueAsString(sampleDto)
        redisTemplate2.opsForValue().set("test_dto2", jsonStr)

        val jsonStr2 = redisTemplate2.opsForValue().get("test_dto2")
        return om.readValue(jsonStr2 ?: "{}", SampleDto::class.java)
    }
}

参考

Kotlin、難しいです。。。
謎だらけです。

GitHub spring boot 2.0
GitHub spring boot 1.5

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2