虽然网上已经有很多使用AOP存入日志了,但我这个不一样。
1.使用最简单的代码直接从注解中获取值
2.支持SEL表达式获取参数中的值
注意事项:如果不用MongoDB就换成自己的方式,简单改一下罗。上代码了。
1.创建AOP拦截类 基本结构不用多说了
2.重点来了,将注解作为参数直接传入,即可直接获取注解中的值。无需通过反射获取。
/**
* 需要切入的注解
*/
@Pointcut("@annotation(post2netAnno)")
public void initPost2netAnno(Post2MongodbAnno post2netAnno) {
}
@Before("initPost2netAnno(post2netAnno)")
public void doBefore(JoinPoint joinPoint, Post2MongodbAnno post2netAnno) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//url
log.info("url={}",request.getRequestURL());
//method
log.info("method={}",request.getMethod());
//ip
log.info("id={}",request.getRemoteAddr());
//class_method
log.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
//args[]
ObjectMapper mapper = new ObjectMapper();
try {
String param = mapper.writeValueAsString(joinPoint.getArgs());
log.info("args={}",param);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Around("initPost2netAnno(post2netAnno)")
public Object around(ProceedingJoinPoint pjp, Post2MongodbAnno post2netAnno) throws Throwable {
long startTime = System.currentTimeMillis();
Object o = null;
Object[] args = pjp.getArgs();
final Object param = args[0];
StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(pjp.getArgs());
standardEvaluationContext = setContextVariables(standardEvaluationContext, pjp);
try {
o = pjp.proceed();
sava2mogodb(standardEvaluationContext,post2netAnno,param,o,System.currentTimeMillis() - startTime);
log.info("☢☢☢:执行结果:{}",o);
return o;
}catch (Exception e){
//其他运行异常统一处理
log.error(e.toString()+":"+e.getMessage());
e.printStackTrace();
Result re = Result.buildFail();
re.setMsg(e.getMessage());
sava2mogodb(standardEvaluationContext,post2netAnno,param,re,System.currentTimeMillis() - startTime);
return re;
}
}
3.通过SEL表达式获取 参数中的值
private StandardEvaluationContext setContextVariables(StandardEvaluationContext standardEvaluationContext, ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method targetMethod = methodSignature.getMethod();
LocalVariableTableParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
String[] parametersName = parameterNameDiscoverer.getParameterNames(targetMethod);
if(args ==null|| args.length<=0) {
return standardEvaluationContext;
}
for(int i =0;i < args.length;i++) {
standardEvaluationContext.setVariable(parametersName[i],args[i]);
}
return standardEvaluationContext;
}
/**
* 通过key SEL表达式获取值
* @Author 张鹏
* @Date 2018/8/24 15:22
* @param key
* @param context
* @return
*/
private String getElValue(String key,StandardEvaluationContext context) {
if(StringUtils.isBlank(key)){
return "";
}
ExpressionParser parser =new SpelExpressionParser();
Expression exp = parser.parseExpression(key);
String value = exp.getValue(context,String.class);
return value;
}
4.大功告成,看看如何使用吧
框起来的就是SEL表达式罗。
注解中的内容怎么定义,我就不多说了。该有的关键代码已经全部加上去了