SpEl 實現(xiàn)自定義日志記錄

在前面我們介紹了SpEl(Spring Expression Language)解析與Spring SpEl高級語法,但是SpEl在時間的開發(fā)中能幫助我們做些什么呢?該如何與自己的業(yè)務進行匹配呢?本講將介紹一種使用方式,Aop + SpEl實現(xiàn)日志記錄!主要是通過SpEl實現(xiàn)自定義的記錄.Aop大家應該都很熟悉,這里不做過多介紹,如果不是很了解,可以先閱讀Spring Aop 核心概念 ,下面我將進行核心的業(yè)務開發(fā)。
自定義注解
我們將自定義一個注解,用與攔截
(ElementType.METHOD)(RetentionPolicy.RUNTIME)public DemoLog {String name() default "demo";String el();}
Aop 實現(xiàn)
這里我們采用@Around的方式,在方法前進行監(jiān)聽,與發(fā)生異常時進行監(jiān)聽
4jpublic class LogAspect {(value = "@annotation(DemoLog)")public void logAspect() {}/*** 環(huán)繞處理** @param joinPoint* @throws Throwable*/(value = "logAspect()")public Object getAroundLog(ProceedingJoinPoint joinPoint) throws Throwable {Object proceed;try {//前置處理saveLogAspect(joinPoint, null);proceed = joinPoint.proceed();return proceed;} catch (Throwable throwable) {saveLogAspect(joinPoint, throwable);throw new RuntimeException(throwable.getMessage());}}private void saveLogAspect(JoinPoint joinPoint, Throwable throwable) {MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();try {// 獲取自定義注解DemoLog demoLog = methodSignature.getMethod().getAnnotation(DemoLog.class);if (Objects.nonNull(demoLog)) {Object spEl = AspectExpress.getSpEl(joinPoint, methodSignature, demoLog.el(), Object.class);if (log.isInfoEnabled()) {log.info(" SpelLog {}", spEl);}}} catch (Exception e) {log.error(e.getMessage());}}}
自定義 SpEl解析器
我們通過自定義SpEL解析的方式實現(xiàn)
public class AspectExpress {public static <T> T getSpEl(JoinPoint joinPoint, MethodSignature methodSignature, String el, Class<T> clazz){EvaluationContext context = getContext(joinPoint.getArgs(), methodSignature.getMethod());return getValue(context, el, clazz);}/*** 獲取spel 定義的參數(shù)值** @param context 參數(shù)容器* @param key key* @param clazz 需要返回的類型* @param <T> 返回泛型* @return 參數(shù)值*/private static <T> T getValue(EvaluationContext context, String key, Class<T> clazz) {SpelExpressionParser spelExpressionParser = new SpelExpressionParser();Expression expression = spelExpressionParser.parseExpression(key);return expression.getValue(context, clazz);}/*** 獲取參數(shù)容器** @param arguments 方法的參數(shù)列表* @param signatureMethod 被執(zhí)行的方法體* @return 裝載參數(shù)的容器*/private static EvaluationContext getContext(Object[] arguments, Method signatureMethod) {String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(signatureMethod);if (parameterNames == null) {throw new RuntimeException("參數(shù)列表不能為null");}EvaluationContext context = new StandardEvaluationContext();for (int i = 0; i < arguments.length; i++) {context.setVariable(parameterNames[i], arguments[i]);}return context;}}
使用方式
public class SpElDemo {public void get( Integer id){}public void get(SecurityProperties.User user){}}

加上以SpEl的功能可以讓我們的Aop操作更加強大。也可以實現(xiàn)更多的處理,可以是我們的日志更加豐富
評論
圖片
表情
