Use interfaces + JDK dynamic proxies instead of CGLIB

It allows to remove open keyword on repositories
This commit is contained in:
Sebastien Deleuze
2016-05-09 23:07:35 +02:00
parent aed05d1a3c
commit ff2e3abe00
5 changed files with 43 additions and 14 deletions

View File

@@ -12,6 +12,7 @@ import org.springframework.boot.CommandLineRunner
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.annotation.Bean
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.transaction.annotation.EnableTransactionManagement
import javax.sql.DataSource
@@ -30,6 +31,9 @@ open class Application {
@Bean
open fun transactionManager(dataSource: DataSource) = SpringTransactionManager(dataSource)
@Bean // PersistenceExceptionTranslationPostProcessor with proxyTargetClass=false, see https://github.com/spring-projects/spring-boot/issues/1844
open fun persistenceExceptionTranslationPostProcessor() = PersistenceExceptionTranslationPostProcessor()
@Bean
open fun init(ur: UserRepository, mr: MessageRepository) = CommandLineRunner {
ur.createTable()

View File

@@ -0,0 +1,13 @@
package io.spring.messenger.repository
import org.postgis.PGbox2d
import org.postgis.Point
interface CrudRepository<T, K> {
fun createTable()
fun create(m: T): T
fun findAll(): Iterable<T>
fun deleteAll(): Int
fun findByBoundingBox(box: PGbox2d): Iterable<T>
fun updateLocation(userName:K, location: Point)
}

View File

@@ -6,25 +6,33 @@ import io.spring.messenger.within
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.statements.UpdateBuilder
import org.postgis.PGbox2d
import org.postgis.Point
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
interface MessageRepository: CrudRepository<Message, Int>
@Repository
@Transactional // Should be at @Service level in real applications
open class MessageRepository() {
class DefaultMessageRepository() : MessageRepository {
open fun createTable() = SchemaUtils.create(Messages)
override fun createTable() = SchemaUtils.create(Messages)
open fun create(m: Message): Message {
override fun create(m: Message): Message {
m.id = Messages.insert(toRow(m)).get(Messages.id)
return m
}
open fun findAll() = Messages.selectAll().map { fromRow(it) }
override fun findAll() = Messages.selectAll().map { fromRow(it) }
open fun findByBoundingBox(box: PGbox2d) = Messages.select { Messages.location within box }.map { fromRow(it) }
override fun findByBoundingBox(box: PGbox2d) = Messages.select { Messages.location within box }.map { fromRow(it) }
open fun deleteAll() = Messages.deleteAll()
override fun updateLocation(id:Int, location: Point) {
location.srid = 4326
Messages.update({ Messages.id eq id}) { it[Messages.location] = location}
}
override fun deleteAll() = Messages.deleteAll()
fun toRow(m: Message): Messages.(UpdateBuilder<*>) -> Unit = {
if (m.id != null) it[id] = m.id

View File

@@ -10,24 +10,29 @@ import org.postgis.Point
import org.springframework.stereotype.Repository
import org.springframework.transaction.annotation.Transactional
interface UserRepository: CrudRepository<User, String>
@Repository
@Transactional // Should be at @Service level in real applications
open class UserRepository() {
class DefaultUserRepository() : UserRepository {
open fun createTable() = SchemaUtils.create(Users)
override fun createTable() = SchemaUtils.create(Users)
open fun create(user: User) = Users.insert( toRow(user) )
override fun create(user: User): User {
Users.insert(toRow(user))
return user
}
open fun updateLocation(userName:String, location: Point) = {
override fun updateLocation(userName:String, location: Point) {
location.srid = 4326
Users.update({Users.userName eq userName}) { it[Users.location] = location}
}
open fun findAll() = Users.selectAll().map { fromRow(it) }
override fun findAll() = Users.selectAll().map { fromRow(it) }
open fun findByBoundingBox(box: PGbox2d) = Users.select { Users.location within box }.map { fromRow(it) }
override fun findByBoundingBox(box: PGbox2d) = Users.select { Users.location within box }.map { fromRow(it) }
open fun deleteAll() = Users.deleteAll()
override fun deleteAll() = Users.deleteAll()
fun toRow(u: User): Users.(UpdateBuilder<*>) -> Unit = {
it[userName] = u.userName

View File

@@ -5,7 +5,6 @@ import io.spring.messenger.repository.UserRepository
import org.postgis.PGbox2d
import org.postgis.Point
import org.springframework.http.HttpStatus.*
import org.springframework.transaction.annotation.Transactional
import org.springframework.web.bind.annotation.*
@RestController