在Spring AOP透過從annotation advice取得方法的annotation。
也就是對方法上標注的annotation做advice切面,例如「Spring AOP 使用annotation 對方法做log」。
下面的DemoController.doTest()
透過標註@LogInfo
來被LogInfoAdvice
做advice。
DemoController
package com.abc.demo.controller;
import com.abc.demo.annotation.LogInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestParam
@RestController
public class DemoController {
@LogInfo(message = "hello") // <-- advice
@GetMapping(value = "/test")
public void doTest(@RequestParam String name, @RequestParam Integer age) {
System.out.println("do something...");
}
}
從ProceedingJoinPoint
取得annotation@LogInfo
的方法如下。透過從JoinPoint
取得MethodSignature
來得到annotation物件。
LogInfoAdvice
package com.abc.demo.aop;
import com.cherri.acs_kernel.annotation.LogInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;
@Aspect
@Component
public class LogInfoAspect {
@Autowired
private ObjectMapper objectMapper;
@Around("@annotation(com.abc.demo.annotation.LogInfo)")
public Object logInfo(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String className = signature.getDeclaringType().getSimpleName(); // 取得方法所在的類別名稱
Method method = signature.getMethod(); // 取得被annotation標注的方法
String methodName = method.getName(); // 取得方法名稱
LogInfo logInfo = method.getAnnotation(LogInfo.class); // 取得標注的annotation
Parameter[] parameters = method.getParameters(); // 取得方法輸入參數資訊
Object[] args = joinPoint.getArgs(); // 取得輸入參數值
String paramsMapJsonString = getParamsMapJsonString(parameters, args); // 把輸入參數轉成json字串
/* e.g.
{
"name" : "john",
"age" : 45,
}
*/
...
Object object = joinPoint.proceed();
...
return object;
}
private String getParamsMapJsonString(Parameter[] parameters, Object[] args) {
Map<String, Object> params = new HashMap<>();
for (int i = 0 ; i < parameters.length; i++) {
params.put(parameters[i].getName(), args[i]);
}
try {
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(params);
} catch (JsonProcessingException e) {
log.error("parse args to json error, args={}", args);
return "";
}
}
}
沒有留言:
張貼留言