修改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接口
*
* @param name 业务名称
* @param clazz 试图业务对象
* @param service 业务domain服务
* @param query 业务查询服务
* @param logger 日志组件
*/
open class Application<TCommand : ICommand, TView, TKey>(
open class Application<TCommand : ICommand, TView, ID>(
override var name: String,
override var clazz: Class<TView>,
override var service: IService<TKey>,
override var service: IService<ID>,
override var query: IQuery,
override var logger: ILogger,
) : ICommandApp<TCommand, TKey>, IQueryApp<TView, TKey> {
) : ICommandApp<TCommand, ID>, IQueryApp<TView, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null

View File

@@ -1,30 +1,38 @@
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.data.serialization.json.IJsonSerializer
import com.synebula.gaea.domain.model.AggregateRoot
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.query.IQuery
import javax.annotation.Resource
/**
* 联合服务同时实现了ILazyCommandApp和IQueryApp接口
* 简单的服务, 取消了Command对象
*
* @param name 业务名称
* @param clazz 业务对象类型
* @param service 业务domain服务
* @param query 业务查询服务
* @param logger 日志组件
*/
open class LazyApplication<TRoot : IAggregateRoot<TKey>, TKey>(
open class SimpleApplication<TRoot : IAggregateRoot<ID>, ID>(
override var name: String,
override var clazz: Class<TRoot>, //view class type
override var service: ILazyService<TRoot, TKey>,
override var clazz: Class<TRoot>,
override var service: ISimpleService<TRoot, ID>,
override var query: IQuery,
override var logger: ILogger,
) : ILazyCommandApp<TRoot, TKey>, IQueryApp<TRoot, TKey> {
) : ISimpleCommandApp<TRoot, ID>, IQueryApp<TRoot, ID> {
@Resource
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 logger 日志组件
*/
open class CommandApp<TCommand : ICommand, TKey>(
open class CommandApp<TCommand : ICommand, ID>(
override var name: String,
override var service: IService<TKey>,
override var service: IService<ID>,
override var logger: ILogger,
) : ICommandApp<TCommand, TKey> {
) : ICommandApp<TCommand, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null
}

View File

@@ -16,10 +16,10 @@ import org.springframework.web.bind.annotation.*
* @version 0.1
* @since 2020-05-15
*/
interface ICommandApp<TCommand : ICommand, TKey> : IApplication {
interface ICommandApp<TCommand : ICommand, ID> : IApplication {
var jsonSerializer: IJsonSerializer?
var service: IService<TKey>
var service: IService<ID>
@PostMapping
@MethodName("添加")
@@ -29,14 +29,14 @@ interface ICommandApp<TCommand : ICommand, TKey> : IApplication {
@PutMapping("/{id:.+}")
@MethodName("更新")
fun update(@PathVariable id: TKey, @RequestBody command: TCommand): HttpMessage {
fun update(@PathVariable id: ID, @RequestBody command: TCommand): HttpMessage {
this.service.update(id, command)
return HttpMessage()
}
@DeleteMapping("/{id:.+}")
@MethodName("删除")
fun remove(@PathVariable id: TKey): HttpMessage {
fun remove(@PathVariable id: ID): HttpMessage {
val msg = HttpMessage()
try {
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.serialization.json.IJsonSerializer
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.*
/**
@@ -16,10 +16,10 @@ import org.springframework.web.bind.annotation.*
* @version 0.1
* @since 2020-05-15
*/
interface ILazyCommandApp<TRoot : IAggregateRoot<TKey>, TKey> : IApplication {
interface ISimpleCommandApp<TRoot : IAggregateRoot<ID>, ID> : IApplication {
var jsonSerializer: IJsonSerializer?
var service: ILazyService<TRoot, TKey>
var service: ISimpleService<TRoot, ID>
@PostMapping
@MethodName("添加")
@@ -29,14 +29,14 @@ interface ILazyCommandApp<TRoot : IAggregateRoot<TKey>, TKey> : IApplication {
@PutMapping("/{id:.+}")
@MethodName("更新")
fun update(@PathVariable id: TKey, @RequestBody entity: TRoot): HttpMessage {
fun update(@PathVariable id: ID, @RequestBody entity: TRoot): HttpMessage {
this.service.update(id, entity)
return HttpMessage()
}
@DeleteMapping("/{id:.+}")
@MethodName("删除")
fun remove(@PathVariable id: TKey): HttpMessage {
fun remove(@PathVariable id: ID): HttpMessage {
val msg = HttpMessage()
try {
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.domain.model.IAggregateRoot
import com.synebula.gaea.domain.service.ILazyService
import com.synebula.gaea.domain.service.ISimpleService
import com.synebula.gaea.log.ILogger
import javax.annotation.Resource
@@ -13,11 +13,11 @@ import javax.annotation.Resource
* @param service 业务domain服务
* @param logger 日志组件
*/
open class LazyCommandApp<TRoot : IAggregateRoot<TKey>, TKey>(
open class SimpleCommandApp<TRoot : IAggregateRoot<ID>, ID>(
override var name: String,
override var service: ILazyService<TRoot, TKey>,
override var service: ISimpleService<TRoot, ID>,
override var logger: ILogger,
) : ILazyCommandApp<TRoot, TKey> {
) : ISimpleCommandApp<TRoot, ID> {
@Resource
override var jsonSerializer: IJsonSerializer? = null
}

View File

@@ -1,12 +1,12 @@
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.springframework.stereotype.Component
@Component
class DozerConverter : IObjectConverter {
class DozerConverter : IObjectMapper {
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的行数列数有限制
var row = sheet.createRow(0)
row.height = 25 * 20
row.height = (25 * 20).toShort()
var cell: HSSFCell
//创建标题
for (col in data.columnNames.indices) {
@@ -69,7 +69,7 @@ object Excel {
for (i in data.data.indices) {
try {
row = sheet.createRow(i + 1)
row.height = 20 * 20
row.height = (20 * 20).toShort()
col = 0
while (col < data.data[i].size) {
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 org.springframework.beans.factory.annotation.Autowired
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.WebSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.web.SecurityFilterChain
import org.springframework.stereotype.Component
import org.springframework.web.cors.CorsConfiguration
import org.springframework.web.cors.CorsConfigurationSource
@@ -16,38 +16,41 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource
@Component
@EnableWebSecurity
class WebSecurity : WebSecurityConfigurerAdapter() {
class WebSecurity {
@Autowired
lateinit var tokenManager: TokenManager
@Autowired
lateinit var authenticationManager: AuthenticationManager
/**
* 安全配置
*/
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
fun filterChain(http: HttpSecurity): SecurityFilterChain {
// 跨域共享
http.cors()
.and().csrf().disable() // 跨域伪造请求限制无效
.authorizeRequests()
.anyRequest().authenticated()// 资源任何人都可访问
.and()
.addFilter(WebAuthorization(authenticationManager(), tokenManager))// 添加JWT鉴权拦截器
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 设置Session的创建策略为Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
.and()
.exceptionHandling()
.authenticationEntryPoint { _, response, _ ->
response.status = Status.Success
response.characterEncoding = "utf-8"
response.contentType = "text/javascript;charset=utf-8"
response.writer.print(HttpMessage(Status.Unauthorized, "用户未登录,请重新登录后尝试!"))
}
.and().csrf().disable() // 跨域伪造请求限制无效
.authorizeRequests()
.anyRequest().authenticated()// 资源任何人都可访问
.and()
.addFilter(WebAuthorization(authenticationManager, tokenManager))// 添加JWT鉴权拦截器
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 设置Session的创建策略为Spring Security永不创建HttpSession 不使用HttpSession来获取SecurityContext
.and()
.exceptionHandling()
.authenticationEntryPoint { _, response, _ ->
response.status = Status.Success
response.characterEncoding = "utf-8"
response.contentType = "text/javascript;charset=utf-8"
response.writer.print(HttpMessage(Status.Unauthorized, "用户未登录,请重新登录后尝试!"))
}
return http.build()
}
@Throws(Exception::class)
override fun configure(web: WebSecurity) {
web.ignoring().antMatchers("/sign/**")
fun filterChain(): WebSecurityCustomizer {
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.RequestParam
interface IQueryApp<TView, TKey> : IApplication {
interface IQueryApp<TView, ID> : IApplication {
/**
* 查询服务
*/
@@ -22,7 +22,7 @@ interface IQueryApp<TView, TKey> : IApplication {
@MethodName("获取数据")
@GetMapping("/{id:.+}")
fun get(@PathVariable id: TKey): HttpMessage {
fun get(@PathVariable id: ID): HttpMessage {
val data = this.query.get(id, clazz)
val msg = HttpMessage()
msg.data = data

View File

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

View File

@@ -13,29 +13,32 @@ import org.springframework.data.mongodb.core.query.Query
*/
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)
}
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> get(
id: TKey,
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> get(
id: ID,
clazz: Class<TAggregateRoot>,
): TAggregateRoot? {
return this.repo.findOne(whereId(id), clazz)
}
override fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(
obj: TAggregateRoot,
clazz: Class<TAggregateRoot>
override fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(
obj: TAggregateRoot,
clazz: Class<TAggregateRoot>,
) {
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)
}
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)
}

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 消息数据类型
*/
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
open class Message {
open class StatusMessage {
/**
* 状态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 src 源数据
* @param targetClass 目标对象。
* @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 <T> 目标数据类型
*
* @param src 源数据
* @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
import com.synebula.gaea.data.serialization.IDeserializer
/**
* 序列化器
*/
interface IJsonDeserializer {
/**
* 反序列化
*
* @param <T> 目标数据类型
* @param src Json字符串数据
* @return 目标数据
*/
fun <T> deserialize(src: String): T
}
interface IJsonDeserializer : IDeserializer<String>

View File

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

View File

@@ -1,5 +1,5 @@
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
}

View File

@@ -1,3 +1,3 @@
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
**/
interface IAggregateRoot<TKey> : IEntity<TKey> {
interface IAggregateRoot<ID> : IEntity<ID> {
/**
* 实体对象是否有效。

View File

@@ -5,13 +5,13 @@ package com.synebula.gaea.domain.model
*
* @author alex
*
* @param <TKey> 主键的类型。
* @param <ID> 主键的类型。
**/
interface IEntity<TKey> {
interface IEntity<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

View File

@@ -13,7 +13,7 @@ interface IRepository {
* @param obj 需要插入的对象。
* @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 需要插入的对象。
* @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 需要更新的对象。
* @return
*/
fun <TAggregateRoot : IAggregateRoot<TKey>, TKey> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>)
fun <TAggregateRoot : IAggregateRoot<ID>, ID> update(obj: TAggregateRoot, clazz: Class<TAggregateRoot>)
/**
* 通过id删除该条数据
@@ -37,7 +37,7 @@ interface IRepository {
* @param id id
* @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获取对象。
@@ -46,7 +46,7 @@ interface IRepository {
* @param clazz 操作数据的类型
* @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
* @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
* @return
*/
fun remove(id: TKey)
fun remove(id: ID)
/**
* 根据ID获取对象。
@@ -47,16 +47,7 @@ interface ISpecificRepository<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
* @param id 对象ID。
* @return
*/
fun get(id: TKey): TAggregateRoot
/**
* 根据ID获取对象。
*
* @param id id
* @param clazz 操作数据的类型
* @return 聚合根
*/
fun <T : IAggregateRoot<TKey>, TKey> get(id: TKey, clazz: Class<T>): T
fun get(id: ID): TAggregateRoot
/**

View File

@@ -12,19 +12,19 @@ interface IContext : IUnitOfWork {
* 将指定的聚合根标注为“新建”状态。
* @param obj
*/
fun <TType : IAggregateRoot<TKey>, TKey> add(obj: TType)
fun <TType : IAggregateRoot<ID>, ID> add(obj: TType)
/**
* 将指定的聚合根标注为“更改”状态。
*
* @param obj
*/
fun <TType : IAggregateRoot<TKey>, TKey> update(obj: TType)
fun <TType : IAggregateRoot<ID>, ID> update(obj: TType)
/**
* 将指定的聚合根标注为“删除”状态。
*
* @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
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
@@ -11,24 +11,24 @@ import com.synebula.gaea.log.ILogger
* @version 0.0.1
* @since 2016年9月18日 下午2:23:15
*/
interface IService<TKey> {
interface IService<ID> {
/**
* 日志组件。
*/
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 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
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.log.ILogger
@@ -12,24 +12,24 @@ import com.synebula.gaea.log.ILogger
* @version 0.0.1
* @since 2016年9月18日 下午2:23:15
*/
interface ILazyService<TAggregateRoot : IAggregateRoot<TKey>, TKey> {
interface ISimpleService<TAggregateRoot : IAggregateRoot<ID>, ID> {
/**
* 日志组件
*/
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 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
import com.synebula.gaea.data.IObjectConverter
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.repository.IRepository
import com.synebula.gaea.log.ILogger
@@ -14,30 +14,30 @@ import com.synebula.gaea.log.ILogger
*
* @param repository 仓储对象
* @param clazz 聚合根类对象
* @param converter 对象转换组件
* @param deserializer 对象转换组件
* @param logger 日志组件
* @author alex
* @version 0.1
* @since 2020-05-17
*/
open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
protected open var clazz: Class<TAggregateRoot>,
protected open var repository: IRepository,
protected open var converter: IObjectConverter,
override var logger: ILogger
) : IService<TKey> {
open class Service<TAggregateRoot : IAggregateRoot<ID>, ID>(
protected open var clazz: Class<TAggregateRoot>,
protected open var repository: IRepository,
protected open var deserializer: IObjectMapper,
override var logger: ILogger,
) : IService<ID> {
/**
* 删除对象前执行监听器。
*/
protected val beforeRemoveListeners = mutableMapOf<String, (id: TKey) -> Message>()
protected val beforeRemoveListeners = mutableMapOf<String, (id: ID) -> StatusMessage>()
/**
* 添加一个删除对象前执行监听器。
* @param key 监听器标志。
* @param func 监听方法。
*/
override fun addBeforeRemoveListener(key: String, func: (id: TKey) -> Message) {
override fun addBeforeRemoveListener(key: String, func: (id: ID) -> StatusMessage) {
this.beforeRemoveListeners[key] = func
}
@@ -49,23 +49,23 @@ open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
this.beforeRemoveListeners.remove(key)
}
override fun add(command: ICommand): DataMessage<TKey> {
val msg = DataMessage<TKey>()
val root = this.convert(command)
override fun add(command: ICommand): DataMessage<ID> {
val msg = DataMessage<ID>()
val root = this.deserialize(command)
this.repository.add(root, this.clazz)
msg.data = root.id
return msg
}
override fun update(id: TKey, command: ICommand) {
val root = this.convert(command)
override fun update(id: ID, command: ICommand) {
val root = this.deserialize(command)
root.id = id
this.repository.update(root, this.clazz)
}
override fun remove(id: TKey) {
override fun remove(id: ID) {
val functions = this.beforeRemoveListeners.values
var msg: Message
var msg: StatusMessage
for (func in functions) {
msg = func(id)
if (!msg.success()) {
@@ -81,9 +81,9 @@ open class Service<TAggregateRoot : IAggregateRoot<TKey>, TKey>(
* @param command 需要转换的命令
* @return 聚合根
*/
protected open fun convert(command: ICommand): TAggregateRoot {
protected open fun deserialize(command: ICommand): TAggregateRoot {
try {
return converter.convert(command, this.clazz)
return deserializer.deserialize(command, this.clazz)
} catch (ex: Exception) {
throw RuntimeException("command not match aggregate root", ex)
}

View File

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

View File

@@ -12,7 +12,7 @@ interface IQuery {
* @param id 对象Key。
* @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
}
}