修改ID泛型名称,重构Serialization内容

This commit is contained in:
2022-07-27 15:23:19 +08:00
parent 7692fb502b
commit a0cfba5dd9
37 changed files with 210 additions and 189 deletions

View File

@@ -13,17 +13,18 @@ import javax.annotation.Resource
* 联合服务同时实现了ICommandApp和IQueryApp接口 * 联合服务同时实现了ICommandApp和IQueryApp接口
* *
* @param name 业务名称 * @param name 业务名称
* @param clazz 试图业务对象
* @param service 业务domain服务 * @param service 业务domain服务
* @param query 业务查询服务 * @param query 业务查询服务
* @param logger 日志组件 * @param logger 日志组件
*/ */
open class Application<TCommand : ICommand, TView, TKey>( open class Application<TCommand : ICommand, TView, ID>(
override var name: String, override var name: String,
override var clazz: Class<TView>, override var clazz: Class<TView>,
override var service: IService<TKey>, override var service: IService<ID>,
override var query: IQuery, override var query: IQuery,
override var logger: ILogger, override var logger: ILogger,
) : ICommandApp<TCommand, TKey>, IQueryApp<TView, TKey> { ) : ICommandApp<TCommand, ID>, IQueryApp<TView, ID> {
@Resource @Resource
override var jsonSerializer: IJsonSerializer? = null override var jsonSerializer: IJsonSerializer? = null

View File

@@ -1,30 +1,38 @@
package com.synebula.gaea.app package com.synebula.gaea.app
import com.synebula.gaea.app.cmd.ILazyCommandApp import com.google.common.reflect.TypeToken
import com.synebula.gaea.app.cmd.ISimpleCommandApp
import com.synebula.gaea.app.query.IQueryApp import com.synebula.gaea.app.query.IQueryApp
import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.domain.model.AggregateRoot
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.domain.service.ILazyService import com.synebula.gaea.domain.service.ISimpleService
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.IQuery
import javax.annotation.Resource import javax.annotation.Resource
/** /**
* 联合服务同时实现了ILazyCommandApp和IQueryApp接口 * 简单的服务, 取消了Command对象
* *
* @param name 业务名称 * @param name 业务名称
* @param clazz 业务对象类型
* @param service 业务domain服务 * @param service 业务domain服务
* @param query 业务查询服务 * @param query 业务查询服务
* @param logger 日志组件 * @param logger 日志组件
*/ */
open class LazyApplication<TRoot : IAggregateRoot<TKey>, TKey>( open class SimpleApplication<TRoot : IAggregateRoot<ID>, ID>(
override var name: String, override var name: String,
override var clazz: Class<TRoot>, //view class type override var clazz: Class<TRoot>,
override var service: ILazyService<TRoot, TKey>, override var service: ISimpleService<TRoot, ID>,
override var query: IQuery, override var query: IQuery,
override var logger: ILogger, override var logger: ILogger,
) : ILazyCommandApp<TRoot, TKey>, IQueryApp<TRoot, TKey> { ) : ISimpleCommandApp<TRoot, ID>, IQueryApp<TRoot, ID> {
@Resource @Resource
override var jsonSerializer: IJsonSerializer? = null override var jsonSerializer: IJsonSerializer? = null
}
fun main() {
val rawType = TypeToken.of(AggregateRoot::class.java).types.rawTypes()
println(rawType)
} }

View File

@@ -13,11 +13,11 @@ import javax.annotation.Resource
* @param service 业务domain服务 * @param service 业务domain服务
* @param logger 日志组件 * @param logger 日志组件
*/ */
open class CommandApp<TCommand : ICommand, TKey>( open class CommandApp<TCommand : ICommand, ID>(
override var name: String, override var name: String,
override var service: IService<TKey>, override var service: IService<ID>,
override var logger: ILogger, override var logger: ILogger,
) : ICommandApp<TCommand, TKey> { ) : ICommandApp<TCommand, ID> {
@Resource @Resource
override var jsonSerializer: IJsonSerializer? = null override var jsonSerializer: IJsonSerializer? = null
} }

View File

@@ -16,10 +16,10 @@ import org.springframework.web.bind.annotation.*
* @version 0.1 * @version 0.1
* @since 2020-05-15 * @since 2020-05-15
*/ */
interface ICommandApp<TCommand : ICommand, TKey> : IApplication { interface ICommandApp<TCommand : ICommand, ID> : IApplication {
var jsonSerializer: IJsonSerializer? var jsonSerializer: IJsonSerializer?
var service: IService<TKey> var service: IService<ID>
@PostMapping @PostMapping
@MethodName("添加") @MethodName("添加")
@@ -29,14 +29,14 @@ interface ICommandApp<TCommand : ICommand, TKey> : IApplication {
@PutMapping("/{id:.+}") @PutMapping("/{id:.+}")
@MethodName("更新") @MethodName("更新")
fun update(@PathVariable id: TKey, @RequestBody command: TCommand): HttpMessage { fun update(@PathVariable id: ID, @RequestBody command: TCommand): HttpMessage {
this.service.update(id, command) this.service.update(id, command)
return HttpMessage() return HttpMessage()
} }
@DeleteMapping("/{id:.+}") @DeleteMapping("/{id:.+}")
@MethodName("删除") @MethodName("删除")
fun remove(@PathVariable id: TKey): HttpMessage { fun remove(@PathVariable id: ID): HttpMessage {
val msg = HttpMessage() val msg = HttpMessage()
try { try {
msg.data = this.service.remove(id) msg.data = this.service.remove(id)

View File

@@ -6,7 +6,7 @@ import com.synebula.gaea.app.struct.HttpMessage
import com.synebula.gaea.data.message.Status import com.synebula.gaea.data.message.Status
import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.domain.service.ILazyService import com.synebula.gaea.domain.service.ISimpleService
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
/** /**
@@ -16,10 +16,10 @@ import org.springframework.web.bind.annotation.*
* @version 0.1 * @version 0.1
* @since 2020-05-15 * @since 2020-05-15
*/ */
interface ILazyCommandApp<TRoot : IAggregateRoot<TKey>, TKey> : IApplication { interface ISimpleCommandApp<TRoot : IAggregateRoot<ID>, ID> : IApplication {
var jsonSerializer: IJsonSerializer? var jsonSerializer: IJsonSerializer?
var service: ILazyService<TRoot, TKey> var service: ISimpleService<TRoot, ID>
@PostMapping @PostMapping
@MethodName("添加") @MethodName("添加")
@@ -29,14 +29,14 @@ interface ILazyCommandApp<TRoot : IAggregateRoot<TKey>, TKey> : IApplication {
@PutMapping("/{id:.+}") @PutMapping("/{id:.+}")
@MethodName("更新") @MethodName("更新")
fun update(@PathVariable id: TKey, @RequestBody entity: TRoot): HttpMessage { fun update(@PathVariable id: ID, @RequestBody entity: TRoot): HttpMessage {
this.service.update(id, entity) this.service.update(id, entity)
return HttpMessage() return HttpMessage()
} }
@DeleteMapping("/{id:.+}") @DeleteMapping("/{id:.+}")
@MethodName("删除") @MethodName("删除")
fun remove(@PathVariable id: TKey): HttpMessage { fun remove(@PathVariable id: ID): HttpMessage {
val msg = HttpMessage() val msg = HttpMessage()
try { try {
msg.data = this.service.remove(id) msg.data = this.service.remove(id)

View File

@@ -2,7 +2,7 @@ package com.synebula.gaea.app.cmd
import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.domain.service.ILazyService import com.synebula.gaea.domain.service.ISimpleService
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import javax.annotation.Resource import javax.annotation.Resource
@@ -13,11 +13,11 @@ import javax.annotation.Resource
* @param service 业务domain服务 * @param service 业务domain服务
* @param logger 日志组件 * @param logger 日志组件
*/ */
open class LazyCommandApp<TRoot : IAggregateRoot<TKey>, TKey>( open class SimpleCommandApp<TRoot : IAggregateRoot<ID>, ID>(
override var name: String, override var name: String,
override var service: ILazyService<TRoot, TKey>, override var service: ISimpleService<TRoot, ID>,
override var logger: ILogger, override var logger: ILogger,
) : ILazyCommandApp<TRoot, TKey> { ) : ISimpleCommandApp<TRoot, ID> {
@Resource @Resource
override var jsonSerializer: IJsonSerializer? = null override var jsonSerializer: IJsonSerializer? = null
} }

View File

@@ -1,12 +1,12 @@
package com.synebula.gaea.app.component package com.synebula.gaea.app.component
import com.synebula.gaea.data.IObjectConverter import com.synebula.gaea.data.serialization.IObjectMapper
import org.dozer.DozerBeanMapper import org.dozer.DozerBeanMapper
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
@Component @Component
class DozerConverter : IObjectConverter { class DozerConverter : IObjectMapper {
private val converter = DozerBeanMapper() private val converter = DozerBeanMapper()
override fun <T> convert(src: Any, dest: Class<T>): T = converter.map(src, dest) override fun <T> deserialize(src: Any, targetClass: Class<T>): T = converter.map(src, targetClass)
} }

View File

@@ -45,7 +45,7 @@ object Excel {
//声明列对象 //声明列对象
// 第三步在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制 // 第三步在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
var row = sheet.createRow(0) var row = sheet.createRow(0)
row.height = 25 * 20 row.height = (25 * 20).toShort()
var cell: HSSFCell var cell: HSSFCell
//创建标题 //创建标题
for (col in data.columnNames.indices) { for (col in data.columnNames.indices) {
@@ -69,7 +69,7 @@ object Excel {
for (i in data.data.indices) { for (i in data.data.indices) {
try { try {
row = sheet.createRow(i + 1) row = sheet.createRow(i + 1)
row.height = 20 * 20 row.height = (20 * 20).toShort()
col = 0 col = 0
while (col < data.data[i].size) { while (col < data.data[i].size) {
cell = row.createCell(col) cell = row.createCell(col)

View File

@@ -4,11 +4,11 @@ import com.synebula.gaea.app.struct.HttpMessage
import com.synebula.gaea.data.message.Status import com.synebula.gaea.data.message.Status
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.config.http.SessionCreationPolicy import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.web.SecurityFilterChain
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
import org.springframework.web.cors.CorsConfiguration import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource import org.springframework.web.cors.CorsConfigurationSource
@@ -16,38 +16,41 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource
@Component @Component
@EnableWebSecurity class WebSecurity {
class WebSecurity : WebSecurityConfigurerAdapter() {
@Autowired @Autowired
lateinit var tokenManager: TokenManager lateinit var tokenManager: TokenManager
@Autowired
lateinit var authenticationManager: AuthenticationManager
/** /**
* 安全配置 * 安全配置
*/ */
@Throws(Exception::class) @Throws(Exception::class)
override fun configure(http: HttpSecurity) { fun filterChain(http: HttpSecurity): SecurityFilterChain {
// 跨域共享 // 跨域共享
http.cors() http.cors()
.and().csrf().disable() // 跨域伪造请求限制无效 .and().csrf().disable() // 跨域伪造请求限制无效
.authorizeRequests() .authorizeRequests()
.anyRequest().authenticated()// 资源任何人都可访问 .anyRequest().authenticated()// 资源任何人都可访问
.and() .and()
.addFilter(WebAuthorization(authenticationManager(), tokenManager))// 添加JWT鉴权拦截器 .addFilter(WebAuthorization(authenticationManager, tokenManager))// 添加JWT鉴权拦截器
.sessionManagement() .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 设置Session的创建策略为Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 设置Session的创建策略为Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
.and() .and()
.exceptionHandling() .exceptionHandling()
.authenticationEntryPoint { _, response, _ -> .authenticationEntryPoint { _, response, _ ->
response.status = Status.Success response.status = Status.Success
response.characterEncoding = "utf-8" response.characterEncoding = "utf-8"
response.contentType = "text/javascript;charset=utf-8" response.contentType = "text/javascript;charset=utf-8"
response.writer.print(HttpMessage(Status.Unauthorized, "用户未登录,请重新登录后尝试!")) response.writer.print(HttpMessage(Status.Unauthorized, "用户未登录,请重新登录后尝试!"))
} }
return http.build()
} }
@Throws(Exception::class) @Throws(Exception::class)
override fun configure(web: WebSecurity) { fun filterChain(): WebSecurityCustomizer {
web.ignoring().antMatchers("/sign/**") return WebSecurityCustomizer { web -> web.ignoring().antMatchers("/sign/**") }
} }
/** /**

View File

@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RequestParam
interface IQueryApp<TView, TKey> : IApplication { interface IQueryApp<TView, ID> : IApplication {
/** /**
* 查询服务 * 查询服务
*/ */
@@ -22,7 +22,7 @@ interface IQueryApp<TView, TKey> : IApplication {
@MethodName("获取数据") @MethodName("获取数据")
@GetMapping("/{id:.+}") @GetMapping("/{id:.+}")
fun get(@PathVariable id: TKey): HttpMessage { fun get(@PathVariable id: ID): HttpMessage {
val data = this.query.get(id, clazz) val data = this.query.get(id, clazz)
val msg = HttpMessage() val msg = HttpMessage()
msg.data = data msg.data = data

View File

@@ -10,9 +10,9 @@ import com.synebula.gaea.query.IQuery
* @param query 业务查询服务 * @param query 业务查询服务
* @param logger 日志组件 * @param logger 日志组件
*/ */
open class QueryApp<TView, TKey>( open class QueryApp<TView, ID>(
override var name: String, override var name: String,
override var clazz: Class<TView>, override var clazz: Class<TView>,
override var query: IQuery, override var query: IQuery,
override var logger: ILogger, override var logger: ILogger,
) : IQueryApp<TView, TKey> ) : IQueryApp<TView, ID>

View File

@@ -116,7 +116,7 @@ fun Query.where(params: Map<String, Any>?, clazz: Class<*>): Query {
* *
* @param id 业务ID * @param id 业务ID
*/ */
fun <TKey> whereId(id: TKey): Query = Query.query(Criteria.where("_id").`is`(id)) fun <ID> whereId(id: ID): Query = Query.query(Criteria.where("_id").`is`(id))
/** /**
* 获取排序对象 * 获取排序对象

View File

@@ -27,7 +27,7 @@ open class MongodbQuery(var template: MongoTemplate, var logger: ILogger) : IQue
*/ */
var validViewCollection = false var validViewCollection = false
override fun <TView, TKey> get(id: TKey, clazz: Class<TView>): TView? { override fun <TView, ID> get(id: ID, clazz: Class<TView>): TView? {
return this.template.findOne(whereId(id), clazz, this.collection(clazz)) return this.template.findOne(whereId(id), clazz, this.collection(clazz))
} }

View File

@@ -13,29 +13,32 @@ import org.springframework.data.mongodb.core.query.Query
*/ */
open class MongodbRepository(private var repo: MongoTemplate) : IRepository { open class MongodbRepository(private var repo: MongoTemplate) : IRepository {
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> remove(id: TKey, clazz: Class<TAggregateRoot>) { override fun <TAggregateRoot : IAggregateRoot<ID>, ID> remove(id: ID, clazz: Class<TAggregateRoot>) {
this.repo.remove(whereId(id), clazz) this.repo.remove(whereId(id), clazz)
} }
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get( override fun <TAggregateRoot : IAggregateRoot<ID>, ID> get(
id: TKey, id: ID,
clazz: Class<TAggregateRoot>, clazz: Class<TAggregateRoot>,
): TAggregateRoot? { ): TAggregateRoot? {
return this.repo.findOne(whereId(id), clazz) return this.repo.findOne(whereId(id), clazz)
} }
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update( override fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(
obj: TAggregateRoot, obj: TAggregateRoot,
clazz: Class<TAggregateRoot> clazz: Class<TAggregateRoot>,
) { ) {
this.repo.save(obj) this.repo.save(obj)
} }
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) { override fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) {
this.repo.save(obj) this.repo.save(obj)
} }
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: List<TAggregateRoot>, clazz: Class<TAggregateRoot>) { override fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(
obj: List<TAggregateRoot>,
clazz: Class<TAggregateRoot>,
) {
this.repo.insert(obj, clazz) this.repo.insert(obj, clazz)
} }

View File

@@ -1,21 +0,0 @@
package com.synebula.gaea.data
/**
* 对象转换器,支持对象之间的转换。
*
* @author alex
* @version 0.1
* @since 2020-05-15
*/
interface IObjectConverter {
/**
* 转换源对象到目标对象。
*
* @param src 源对象。
* @param dest 目标对象。
* @param <T> 目标对象类型。
* @return 目标对象
*/
fun <T> convert(src: Any, dest: Class<T>): T
}

View File

@@ -8,7 +8,7 @@ import java.util.*
* *
* @param T 消息数据类型 * @param T 消息数据类型
*/ */
open class DataMessage<T>() : Message() { open class DataMessage<T>() : StatusMessage() {
/** /**
* 传递的业务数据 * 传递的业务数据

View File

@@ -0,0 +1,16 @@
package com.synebula.gaea.data.message
/**
* 消息结构
*/
interface IMessage {
/**
* 命令载荷, 实际的业务数据
*/
var message: String
/**
* 时间戳。
*/
var timestamp: Long
}

View File

@@ -1,6 +1,6 @@
package com.synebula.gaea.data.message package com.synebula.gaea.data.message
open class Message { open class StatusMessage {
/** /**
* 状态200成功400错误500异常 * 状态200成功400错误500异常
*/ */

View File

@@ -2,16 +2,17 @@ package com.synebula.gaea.data.serialization
/** /**
* 序列化器 * 序列化器
* @param <S> 源数据类型
*/ */
interface IDeserializer { interface IDeserializer<S> {
/** /**
* 反序列化 * 反序列化
* *
* @param <S> 源数据类型
* @param <T> 目标数据类型 * @param <T> 目标数据类型
* @param src 源数据 * @param src 源数据
* @param targetClass 目标对象。
* @return 目标数据 * @return 目标数据
*/ */
fun <S, T> deserialize(src: S): T fun <T> deserialize(src: S, targetClass: Class<T>): T
} }

View File

@@ -0,0 +1,10 @@
package com.synebula.gaea.data.serialization
/**
* 对象映射器,支持对象之间的转换。
*
* @author alex
* @version 0.1
* @since 2020-05-15
*/
interface IObjectMapper : IDeserializer<Any>

View File

@@ -2,16 +2,16 @@ package com.synebula.gaea.data.serialization
/** /**
* 序列化器 * 序列化器
* @param <T> 目标数据类型
*/ */
interface ISerializer { interface ISerializer<T> {
/** /**
* 序列化 * 序列化
*
* @param <S> 源数据类型 * @param <S> 源数据类型
* @param <T> 目标数据类型 *
* @param src 源数据 * @param src 源数据
* @return 目标数据 * @return 目标数据
*/ */
fun <S, T> serialize(src: S): T fun <S> serialize(src: S): T
} }

View File

@@ -1,15 +1,8 @@
package com.synebula.gaea.data.serialization.json package com.synebula.gaea.data.serialization.json
import com.synebula.gaea.data.serialization.IDeserializer
/** /**
* 序列化器 * 序列化器
*/ */
interface IJsonDeserializer { interface IJsonDeserializer : IDeserializer<String>
/**
* 反序列化
*
* @param <T> 目标数据类型
* @param src Json字符串数据
* @return 目标数据
*/
fun <T> deserialize(src: String): T
}

View File

@@ -1,15 +1,8 @@
package com.synebula.gaea.data.serialization.json package com.synebula.gaea.data.serialization.json
import com.synebula.gaea.data.serialization.ISerializer
/** /**
* 序列化器 * 序列化器
*/ */
interface IJsonSerializer { interface IJsonSerializer : ISerializer<String>
/**
* 序列化
*
* @param <S> 源数据类型
* @param src 源数据
* @return Json字符串
*/
fun <S> serialize(src: S): String
}

View File

@@ -1,5 +1,5 @@
package com.synebula.gaea.domain.model package com.synebula.gaea.domain.model
abstract class AggregateRoot<TKey> : Entity<TKey>(), IAggregateRoot<TKey> { abstract class AggregateRoot<ID> : Entity<ID>(), IAggregateRoot<ID> {
override var alive: Boolean = true override var alive: Boolean = true
} }

View File

@@ -1,3 +1,3 @@
package com.synebula.gaea.domain.model package com.synebula.gaea.domain.model
abstract class Entity<TKey> : IEntity<TKey> abstract class Entity<ID> : IEntity<ID>

View File

@@ -5,7 +5,7 @@ package com.synebula.gaea.domain.model
* *
* @author alex * @author alex
**/ **/
interface IAggregateRoot<TKey> : IEntity<TKey> { interface IAggregateRoot<ID> : IEntity<ID> {
/** /**
* 实体对象是否有效。 * 实体对象是否有效。

View File

@@ -5,13 +5,13 @@ package com.synebula.gaea.domain.model
* *
* @author alex * @author alex
* *
* @param <TKey> 主键的类型。 * @param <ID> 主键的类型。
**/ **/
interface IEntity<TKey> { interface IEntity<ID> {
/** /**
* 实体ID * 实体ID
*/ */
var id: TKey? var id: ID?
} }

View File

@@ -7,7 +7,7 @@ import java.util.*
* 记录信息 * 记录信息
* 添加了创建和修改的人\时间信息 * 添加了创建和修改的人\时间信息
*/ */
abstract class Record<TKey> { abstract class Record<ID> {
//记录增加信息 //记录增加信息
var creator: String? = null var creator: String? = null

View File

@@ -13,7 +13,7 @@ interface IRepository {
* @param obj 需要插入的对象。 * @param obj 需要插入的对象。
* @return 返回原对象如果对象ID为自增则补充自增ID。 * @return 返回原对象如果对象ID为自增则补充自增ID。
*/ */
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(obj: TAggregateRoot, clazz: Class<TAggregateRoot>)
/** /**
* 插入多个个对象。 * 插入多个个对象。
@@ -21,7 +21,7 @@ interface IRepository {
* @param obj 需要插入的对象。 * @param obj 需要插入的对象。
* @return 返回原对象如果对象ID为自增则补充自增ID。 * @return 返回原对象如果对象ID为自增则补充自增ID。
*/ */
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> add(obj: List<TAggregateRoot>, clazz: Class<TAggregateRoot>) fun <TAggregateRoot : IAggregateRoot<ID>, ID> add(obj: List<TAggregateRoot>, clazz: Class<TAggregateRoot>)
/** /**
* 更新对象。 * 更新对象。
@@ -29,7 +29,7 @@ interface IRepository {
* @param obj 需要更新的对象。 * @param obj 需要更新的对象。
* @return * @return
*/ */
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>) fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>)
/** /**
* 通过id删除该条数据 * 通过id删除该条数据
@@ -37,7 +37,7 @@ interface IRepository {
* @param id id * @param id id
* @param clazz 操作数据的类型 * @param clazz 操作数据的类型
*/ */
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> remove(id: TKey, clazz: Class<TAggregateRoot>) fun <TAggregateRoot : IAggregateRoot<ID>, ID> remove(id: ID, clazz: Class<TAggregateRoot>)
/** /**
* 根据ID获取对象。 * 根据ID获取对象。
@@ -46,7 +46,7 @@ interface IRepository {
* @param clazz 操作数据的类型 * @param clazz 操作数据的类型
* @return 聚合根 * @return 聚合根
*/ */
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<TAggregateRoot>): TAggregateRoot? fun <TAggregateRoot : IAggregateRoot<ID>, ID> get(id: ID, clazz: Class<TAggregateRoot>): TAggregateRoot?
/** /**

View File

@@ -10,7 +10,7 @@ import com.synebula.gaea.domain.model.IAggregateRoot
* @param <TAggregateRoot> this T is the parameter * @param <TAggregateRoot> this T is the parameter
* @author alex * @author alex
*/ */
interface ISpecificRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> { interface ISpecificRepository<TAggregateRoot : IAggregateRoot<ID>, ID> {
/** /**
* 仓储的对象类 * 仓储的对象类
@@ -39,7 +39,7 @@ interface ISpecificRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
* @param id * @param id
* @return * @return
*/ */
fun remove(id: TKey) fun remove(id: ID)
/** /**
* 根据ID获取对象。 * 根据ID获取对象。
@@ -47,16 +47,7 @@ interface ISpecificRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
* @param id 对象ID。 * @param id 对象ID。
* @return * @return
*/ */
fun get(id: TKey): TAggregateRoot fun get(id: ID): TAggregateRoot
/**
* 根据ID获取对象。
*
* @param id id
* @param clazz 操作数据的类型
* @return 聚合根
*/
fun <T : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<T>): T
/** /**

View File

@@ -12,19 +12,19 @@ interface IContext : IUnitOfWork {
* 将指定的聚合根标注为“新建”状态。 * 将指定的聚合根标注为“新建”状态。
* @param obj * @param obj
*/ */
fun <TType : IAggregateRoot<TKey>, TKey> add(obj: TType) fun <TType : IAggregateRoot<ID>, ID> add(obj: TType)
/** /**
* 将指定的聚合根标注为“更改”状态。 * 将指定的聚合根标注为“更改”状态。
* *
* @param obj * @param obj
*/ */
fun <TType : IAggregateRoot<TKey>, TKey> update(obj: TType) fun <TType : IAggregateRoot<ID>, ID> update(obj: TType)
/** /**
* 将指定的聚合根标注为“删除”状态。 * 将指定的聚合根标注为“删除”状态。
* *
* @param obj * @param obj
*/ */
fun <TType : IAggregateRoot<TKey>, TKey> remove(obj: TType) fun <TType : IAggregateRoot<ID>, ID> remove(obj: TType)
} }

View File

@@ -1,7 +1,7 @@
package com.synebula.gaea.domain.service package com.synebula.gaea.domain.service
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Message import com.synebula.gaea.data.message.StatusMessage
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
@@ -11,24 +11,24 @@ import com.synebula.gaea.log.ILogger
* @version 0.0.1 * @version 0.0.1
* @since 2016年9月18日 下午2:23:15 * @since 2016年9月18日 下午2:23:15
*/ */
interface IService<TKey> { interface IService<ID> {
/** /**
* 日志组件。 * 日志组件。
*/ */
var logger: ILogger var logger: ILogger
fun add(command: ICommand): DataMessage<TKey> fun add(command: ICommand): DataMessage<ID>
fun update(id: TKey, command: ICommand) fun update(id: ID, command: ICommand)
fun remove(id: TKey) fun remove(id: ID)
/** /**
* 添加一个删除对象前执行监听器。 * 添加一个删除对象前执行监听器。
* @param key 监听器标志。 * @param key 监听器标志。
* @param func 监听方法。 * @param func 监听方法。
*/ */
fun addBeforeRemoveListener(key: String, func: (id: TKey) -> Message) fun addBeforeRemoveListener(key: String, func: (id: ID) -> StatusMessage)
/** /**
* 移除一个删除对象前执行监听器。 * 移除一个删除对象前执行监听器。

View File

@@ -1,7 +1,7 @@
package com.synebula.gaea.domain.service package com.synebula.gaea.domain.service
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Message import com.synebula.gaea.data.message.StatusMessage
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
@@ -12,24 +12,24 @@ import com.synebula.gaea.log.ILogger
* @version 0.0.1 * @version 0.0.1
* @since 2016年9月18日 下午2:23:15 * @since 2016年9月18日 下午2:23:15
*/ */
interface ILazyService<TAggregateRoot : IAggregateRoot<TKey>, TKey> { interface ISimpleService<TAggregateRoot : IAggregateRoot<ID>, ID> {
/** /**
* 日志组件 * 日志组件
*/ */
var logger: ILogger var logger: ILogger
fun add(root: TAggregateRoot): DataMessage<TKey> fun add(root: TAggregateRoot): DataMessage<ID>
fun update(id: TKey, root: TAggregateRoot) fun update(id: ID, root: TAggregateRoot)
fun remove(id: TKey) fun remove(id: ID)
/** /**
* 添加一个删除对象前执行监听器 * 添加一个删除对象前执行监听器
* @param key 监听器标志 * @param key 监听器标志
* @param func 监听方法 * @param func 监听方法
*/ */
fun addBeforeRemoveListener(key: String, func: (id: TKey) -> Message) fun addBeforeRemoveListener(key: String, func: (id: ID) -> StatusMessage)
/** /**
* 移除一个删除对象前执行监听器 * 移除一个删除对象前执行监听器

View File

@@ -1,8 +1,8 @@
package com.synebula.gaea.domain.service package com.synebula.gaea.domain.service
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Message import com.synebula.gaea.data.message.StatusMessage
import com.synebula.gaea.data.serialization.IObjectMapper
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.domain.repository.IRepository import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
@@ -14,30 +14,30 @@ import com.synebula.gaea.log.ILogger
* *
* @param repository 仓储对象 * @param repository 仓储对象
* @param clazz 聚合根类对象 * @param clazz 聚合根类对象
* @param converter 对象转换组件 * @param deserializer 对象转换组件
* @param logger 日志组件 * @param logger 日志组件
* @author alex * @author alex
* @version 0.1 * @version 0.1
* @since 2020-05-17 * @since 2020-05-17
*/ */
open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>( open class Service<TAggregateRoot : IAggregateRoot<ID>, ID>(
protected open var clazz: Class<TAggregateRoot>, protected open var clazz: Class<TAggregateRoot>,
protected open var repository: IRepository, protected open var repository: IRepository,
protected open var converter: IObjectConverter, protected open var deserializer: IObjectMapper,
override var logger: ILogger override var logger: ILogger,
) : IService<TKey> { ) : IService<ID> {
/** /**
* 删除对象前执行监听器。 * 删除对象前执行监听器。
*/ */
protected val beforeRemoveListeners = mutableMapOf<String, (id: TKey) -> Message>() protected val beforeRemoveListeners = mutableMapOf<String, (id: ID) -> StatusMessage>()
/** /**
* 添加一个删除对象前执行监听器。 * 添加一个删除对象前执行监听器。
* @param key 监听器标志。 * @param key 监听器标志。
* @param func 监听方法。 * @param func 监听方法。
*/ */
override fun addBeforeRemoveListener(key: String, func: (id: TKey) -> Message) { override fun addBeforeRemoveListener(key: String, func: (id: ID) -> StatusMessage) {
this.beforeRemoveListeners[key] = func this.beforeRemoveListeners[key] = func
} }
@@ -49,23 +49,23 @@ open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
this.beforeRemoveListeners.remove(key) this.beforeRemoveListeners.remove(key)
} }
override fun add(command: ICommand): DataMessage<TKey> { override fun add(command: ICommand): DataMessage<ID> {
val msg = DataMessage<TKey>() val msg = DataMessage<ID>()
val root = this.convert(command) val root = this.deserialize(command)
this.repository.add(root, this.clazz) this.repository.add(root, this.clazz)
msg.data = root.id msg.data = root.id
return msg return msg
} }
override fun update(id: TKey, command: ICommand) { override fun update(id: ID, command: ICommand) {
val root = this.convert(command) val root = this.deserialize(command)
root.id = id root.id = id
this.repository.update(root, this.clazz) this.repository.update(root, this.clazz)
} }
override fun remove(id: TKey) { override fun remove(id: ID) {
val functions = this.beforeRemoveListeners.values val functions = this.beforeRemoveListeners.values
var msg: Message var msg: StatusMessage
for (func in functions) { for (func in functions) {
msg = func(id) msg = func(id)
if (!msg.success()) { if (!msg.success()) {
@@ -81,9 +81,9 @@ open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
* @param command 需要转换的命令 * @param command 需要转换的命令
* @return 聚合根 * @return 聚合根
*/ */
protected open fun convert(command: ICommand): TAggregateRoot { protected open fun deserialize(command: ICommand): TAggregateRoot {
try { try {
return converter.convert(command, this.clazz) return deserializer.deserialize(command, this.clazz)
} catch (ex: Exception) { } catch (ex: Exception) {
throw RuntimeException("command not match aggregate root", ex) throw RuntimeException("command not match aggregate root", ex)
} }

View File

@@ -1,7 +1,7 @@
package com.synebula.gaea.domain.service package com.synebula.gaea.domain.service
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Message import com.synebula.gaea.data.message.StatusMessage
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.model.IAggregateRoot
import com.synebula.gaea.domain.repository.IRepository import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
@@ -18,23 +18,23 @@ import com.synebula.gaea.log.ILogger
* @version 0.1 * @version 0.1
* @since 2020-05-17 * @since 2020-05-17
*/ */
open class LazyService<TAggregateRoot : IAggregateRoot<TKey>, TKey>( open class SimpleService<TAggregateRoot : IAggregateRoot<ID>, ID>(
protected open var clazz: Class<TAggregateRoot>, protected open var clazz: Class<TAggregateRoot>,
protected open var repository: IRepository, protected open var repository: IRepository,
override var logger: ILogger override var logger: ILogger,
) : ILazyService<TAggregateRoot, TKey> { ) : ISimpleService<TAggregateRoot, ID> {
/** /**
* 删除对象前执行监听器 * 删除对象前执行监听器
*/ */
protected val beforeRemoveListeners = mutableMapOf<String, (id: TKey) -> Message>() protected val beforeRemoveListeners = mutableMapOf<String, (id: ID) -> StatusMessage>()
/** /**
* 添加一个删除对象前执行监听器 * 添加一个删除对象前执行监听器
* @param key 监听器标志 * @param key 监听器标志
* @param func 监听方法 * @param func 监听方法
*/ */
override fun addBeforeRemoveListener(key: String, func: (id: TKey) -> Message) { override fun addBeforeRemoveListener(key: String, func: (id: ID) -> StatusMessage) {
this.beforeRemoveListeners[key] = func this.beforeRemoveListeners[key] = func
} }
@@ -46,21 +46,21 @@ open class LazyService<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
this.beforeRemoveListeners.remove(key) this.beforeRemoveListeners.remove(key)
} }
override fun add(root: TAggregateRoot): DataMessage<TKey> { override fun add(root: TAggregateRoot): DataMessage<ID> {
val msg = DataMessage<TKey>() val msg = DataMessage<ID>()
this.repository.add(root, this.clazz) this.repository.add(root, this.clazz)
msg.data = root.id msg.data = root.id
return msg return msg
} }
override fun update(id: TKey, root: TAggregateRoot) { override fun update(id: ID, root: TAggregateRoot) {
root.id = id root.id = id
this.repository.update(root, this.clazz) this.repository.update(root, this.clazz)
} }
override fun remove(id: TKey) { override fun remove(id: ID) {
val functions = this.beforeRemoveListeners.values val functions = this.beforeRemoveListeners.values
var msg: Message var msg: StatusMessage
for (func in functions) { for (func in functions) {
msg = func(id) msg = func(id)
if (!msg.success()) { if (!msg.success()) {

View File

@@ -12,7 +12,7 @@ interface IQuery {
* @param id 对象Key。 * @param id 对象Key。
* @return 视图结果 * @return 视图结果
*/ */
fun <TView, TKey> get(id: TKey, clazz: Class<TView>): TView? fun <TView, ID> get(id: ID, clazz: Class<TView>): TView?
/** /**
* 根据实体类条件查询所有符合条件记录 * 根据实体类条件查询所有符合条件记录

View File

@@ -0,0 +1,23 @@
package com.synebula.gaea.reflect
import com.synebula.gaea.bus.SubscriberRegistry
object Types {
/**
* 获取类的所有父类型。
*/
fun supertypes(clazz: Class<*>): Set<Class<*>> {
val supertypes = mutableSetOf<Class<*>>()
supertypes.add(clazz)
if (clazz.superclass != null)
supertypes.addAll(SubscriberRegistry.flattenHierarchy(clazz.superclass))
if (clazz.interfaces.isNotEmpty()) {
supertypes.addAll(clazz.interfaces.map { SubscriberRegistry.flattenHierarchy(it) }.reduce { r, c ->
val all = r.toMutableSet()
all.addAll(c)
all
})
}
return supertypes
}
}