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