0.7.0 修改异常日志记录为AOP切面的方式
This commit is contained in:
@@ -21,7 +21,7 @@ allprojects {
|
||||
|
||||
subprojects {
|
||||
ext {
|
||||
version '0.6.1'
|
||||
version '0.7.0'
|
||||
spring_version = "2.3.0.RELEASE"
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ interface IApplication {
|
||||
* 安全执行
|
||||
*/
|
||||
fun safeExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
|
||||
val msg = HttpMessage(Status.Success)
|
||||
val msg = HttpMessage()
|
||||
try {
|
||||
process(msg)
|
||||
logger?.debug(this, "$name business execute success")
|
||||
@@ -37,7 +37,7 @@ interface IApplication {
|
||||
* 可抛出自定义异常信息的安全controller实现了异常捕获和消息组成。
|
||||
*/
|
||||
fun throwExecute(error: String, process: ((msg: HttpMessage) -> Unit)): HttpMessage {
|
||||
val msg = HttpMessage(Status.Success)
|
||||
val msg = HttpMessage()
|
||||
try {
|
||||
process(msg)
|
||||
logger?.debug(this, "$name business execute success")
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.synebula.gaea.app.cmd
|
||||
|
||||
import com.synebula.gaea.app.IApplication
|
||||
import com.synebula.gaea.app.component.HttpMessage
|
||||
import com.synebula.gaea.app.component.aop.annotation.ExceptionMessage
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.data.serialization.json.IJsonSerializer
|
||||
import com.synebula.gaea.domain.service.ICommand
|
||||
@@ -20,40 +21,44 @@ interface ICommandApp<TCommand : ICommand, TKey> : IApplication {
|
||||
|
||||
var service: IService<TKey>?
|
||||
|
||||
@DeleteMapping("/{id:.+}")
|
||||
fun remove(@PathVariable id: TKey): HttpMessage {
|
||||
return this.safeExecute("删除${this.name}[id: $id]失败") {
|
||||
if (this.service != null)
|
||||
it.data = this.service!!.remove(id)
|
||||
else {
|
||||
it.status = Status.Error
|
||||
it.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ExceptionMessage("添加异常")
|
||||
fun add(@RequestBody command: TCommand): HttpMessage {
|
||||
return this.safeExecute("添加${this.name}数据失败 - ${if (jsonSerializer != null) jsonSerializer?.serialize(command) else ""}") {
|
||||
val msg = HttpMessage()
|
||||
if (this.service != null) {
|
||||
val msg = this.service!!.add(command)
|
||||
it.load(msg)
|
||||
msg.load(this.service!!.add(command))
|
||||
} else {
|
||||
it.status = Status.Error
|
||||
it.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
msg.status = Status.Error
|
||||
msg.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
@PutMapping("/{id:.+}")
|
||||
@ExceptionMessage("更新异常")
|
||||
fun update(@PathVariable id: TKey, @RequestBody command: TCommand): HttpMessage {
|
||||
return this.safeExecute("更新${this.name}失败 - ${if (jsonSerializer != null) jsonSerializer?.serialize(command) else ""}") {
|
||||
val msg = HttpMessage()
|
||||
if (this.service != null)
|
||||
this.service!!.update(id, command)
|
||||
else {
|
||||
it.status = Status.Error
|
||||
it.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
}
|
||||
msg.status = Status.Error
|
||||
msg.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
|
||||
@DeleteMapping("/{id:.+}")
|
||||
@ExceptionMessage("删除异常")
|
||||
fun remove(@PathVariable id: TKey): HttpMessage {
|
||||
val msg = HttpMessage()
|
||||
if (this.service != null)
|
||||
msg.data = this.service!!.remove(id)
|
||||
else {
|
||||
msg.status = Status.Error
|
||||
msg.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
return msg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.synebula.gaea.app.component.aop
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.synebula.gaea.app.IApplication
|
||||
import com.synebula.gaea.app.component.HttpMessage
|
||||
import com.synebula.gaea.app.component.aop.annotation.ExceptionMessage
|
||||
import com.synebula.gaea.app.component.aop.annotation.Handler
|
||||
@@ -8,16 +10,15 @@ import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.log.ILogger
|
||||
import org.aspectj.lang.JoinPoint
|
||||
import org.aspectj.lang.ProceedingJoinPoint
|
||||
import org.aspectj.lang.annotation.*
|
||||
import org.springframework.stereotype.Component
|
||||
import org.aspectj.lang.annotation.AfterThrowing
|
||||
import org.aspectj.lang.annotation.Around
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.context.ApplicationContext
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer
|
||||
|
||||
abstract class AppAspect {
|
||||
private var paramDiscover = DefaultParameterNameDiscoverer()
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
class AppAspect {
|
||||
private val mapper = ObjectMapper()
|
||||
|
||||
@Autowired
|
||||
@@ -26,14 +27,15 @@ class AppAspect {
|
||||
@Autowired
|
||||
lateinit var applicationContext: ApplicationContext
|
||||
|
||||
@Pointcut("within(com.synebula..app.*)")
|
||||
fun log() {
|
||||
}
|
||||
/**
|
||||
* 定义切面的方法
|
||||
*/
|
||||
abstract fun func()
|
||||
|
||||
/**
|
||||
* 后置异常通知
|
||||
*/
|
||||
@AfterThrowing("log()", throwing = "ex")
|
||||
@AfterThrowing("func()", throwing = "ex")
|
||||
fun throws(point: JoinPoint, ex: Throwable) {
|
||||
val clazz = point.signature.declaringType
|
||||
logger.error(
|
||||
@@ -45,12 +47,12 @@ class AppAspect {
|
||||
/**
|
||||
* 环绕通知,环绕增强,相当于MethodInterceptor
|
||||
*/
|
||||
@Around("log()")
|
||||
@Around("func()")
|
||||
fun around(point: ProceedingJoinPoint): Any? {
|
||||
val clazz = point.signature.declaringType
|
||||
val func = clazz.methods.find {
|
||||
val clazz = point.`this`.javaClass //获取实际对象的类型避免获取到父类
|
||||
val func = point.signature.declaringType.methods.find {
|
||||
it.name == point.signature.name
|
||||
}!!
|
||||
}!!//获取声明类型中的方法信息
|
||||
val funcAnnotations = func.annotations ?: arrayOf()
|
||||
|
||||
var exceptionMessage = func.name
|
||||
@@ -69,17 +71,27 @@ class AppAspect {
|
||||
}
|
||||
|
||||
return try {
|
||||
val res = point.proceed()
|
||||
res
|
||||
point.proceed()
|
||||
} catch (ex: Throwable) {
|
||||
//找到类的模块名称,否则使用类名
|
||||
var moduleName = clazz.name
|
||||
if (IApplication::class.java.isAssignableFrom(clazz)) {
|
||||
moduleName = (point.`this` as IApplication).name
|
||||
} else {
|
||||
val name = clazz.annotations.find { it is ModuleName }
|
||||
if (name != null && name is ModuleName) {
|
||||
moduleName = name.value
|
||||
}
|
||||
}
|
||||
val message = "$moduleName - $exceptionMessage"
|
||||
logger.error(ex, "$message, args: ${mapper.writeValueAsString(point.args)}")
|
||||
logger.error(
|
||||
ex,
|
||||
"$message。Method args ${paramDiscover.getParameterNames(func)?.contentToString()} values is ${
|
||||
mapper.writeValueAsString(
|
||||
point.args
|
||||
)
|
||||
}"
|
||||
)
|
||||
return HttpMessage(Status.Error, message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.synebula.gaea.app.component.aop.annotation
|
||||
|
||||
import java.lang.annotation.Inherited
|
||||
|
||||
/**
|
||||
* 标记方法安全执行,由AOP负责try catch异常
|
||||
*
|
||||
* @param message 异常消息
|
||||
*/
|
||||
@Inherited
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ExceptionMessage(val message: String)
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.synebula.gaea.app.query
|
||||
|
||||
import com.synebula.gaea.app.IApplication
|
||||
import com.synebula.gaea.app.component.HttpMessage
|
||||
import com.synebula.gaea.app.component.aop.annotation.ExceptionMessage
|
||||
import com.synebula.gaea.data.message.Status
|
||||
import com.synebula.gaea.query.IQuery
|
||||
import com.synebula.gaea.query.Params
|
||||
@@ -21,26 +22,29 @@ interface IQueryApp<TView, TKey> : IApplication {
|
||||
var clazz: Class<TView>
|
||||
|
||||
@GetMapping("/{id:.+}")
|
||||
@ExceptionMessage("获取数据失败")
|
||||
fun get(@PathVariable id: TKey): HttpMessage {
|
||||
return this.doQuery("获取${this.name}数据失败") {
|
||||
return this.doQuery {
|
||||
this.query!!.get(id, clazz)
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ExceptionMessage("获取列表数据失败")
|
||||
fun list(@RequestParam params: LinkedHashMap<String, Any>): HttpMessage {
|
||||
return this.doQuery("获取${this.name}列表数据失败") {
|
||||
return this.doQuery {
|
||||
this.query!!.list(params, clazz)
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/segments/{size}/pages/{page}")
|
||||
@ExceptionMessage("获取分页数据失败")
|
||||
fun paging(
|
||||
@PathVariable size: Int,
|
||||
@PathVariable page: Int,
|
||||
@RequestParam parameters: LinkedHashMap<String, Any>
|
||||
): HttpMessage {
|
||||
return this.doQuery("获取${this.name}分页数据[条数:$size,页码:$page]失败") {
|
||||
return this.doQuery {
|
||||
val data = Params(page, size, parameters)
|
||||
this.query!!.paging(data, clazz)
|
||||
}
|
||||
@@ -50,17 +54,16 @@ interface IQueryApp<TView, TKey> : IApplication {
|
||||
/**
|
||||
* 抽取查询业务判断功能
|
||||
*
|
||||
* @param error 错误消息
|
||||
* @param biz 业务执行逻辑
|
||||
*/
|
||||
fun doQuery(error: String, biz: (() -> Any?)): HttpMessage {
|
||||
return this.safeExecute(error) {
|
||||
fun doQuery(biz: (() -> Any?)): HttpMessage {
|
||||
val msg = HttpMessage()
|
||||
if (this.query != null) {
|
||||
it.data = biz()
|
||||
msg.data = biz()
|
||||
} else {
|
||||
it.status = Status.Error
|
||||
it.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
}
|
||||
msg.status = Status.Error
|
||||
msg.message = "没有对应服务,无法执行该操作"
|
||||
}
|
||||
return msg
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user