在@Value注解内使用SPEL自定义函数方式

网友投稿 587 2022-08-27


在@Value注解内使用SPEL自定义函数方式

目录@Value注解内使用SPEL自定义函数自定义注解支持SpEL表达式1.定义日志注解2.定义spel解析工具类3.定义切面类4.方法上使用日志注解

@Value注解内使用SPEL自定义函数

@Value("#{T(com.cheetah.provider.utils.StringUtil).lower('${cluster.vendor.type}')}")

其中,${cluster.vendor.type}取的application.properties中的配置,com.cheetah.provider.utils.StringUtil#lower是用户自定义函数,

T()运算符的结果是一Class对象,它的真正价值在于它能够访问目标类型的静态方法和常量

自定义注解支持SpEL表达式

利用AOP生成用户操作日志

1.定义日志注解

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface SysLog {

//普通的操作说明

String value() default "";

//spel表达式的操作说明

String spelValue() default "";

}

2.定义spel解析工具类

public class SpelUtil {

/**

* 用于SpEL表达式解析.

*/

private static SpelExpressionParser parser = new SpelExpressionParser();

/**

* 用于获取方法参数定义名字.

*/

private static DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();

public static String generateKeyBySpEL(String spELString, ProceedingJoinPoint joinPoint) {

// 通过joinPoint获取被注解方法

MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

Method method = methodSignature.getMethod();

// 使用spring的DefaultParameterNameDiscoverer获取方法形参名数组

String[] paramNames = nameDiscoverer.getParameterNames(method);

// 解析过后的Spring表达式对象

Expression expression = parser.parseExpression(spELString);

// spring的表达式上下文对象

EvaluationContext context = new StandardEvaluationContext();

// 通过joinPoint获取被注解方法的形参

Object[] args = joinPoint.getArgs();

// 给上下文赋值

for (int i = 0; i < args.length; i++) {

context.setVariable(paramNames[i], args[i]);

}

// 表达式从上下文中计算出实际参数值

/*如:

@annotation(key="#student.name")

method(Student student)

那么就可以解析出方法形参的某属性值,return “xiaoming”;

*/

return expression.getValue(context).toString();

}

}

3.定义切面类KDONL

@Aspect

@Component

public class SysLogAspect {

@Autowired

private LogService logService;

@Autowired

private HttpServletRequest request;

@Pointcut("@annotation(com.ztri.common.annotation.SysLog)")

public void logPointCut() {

}

@Around("logPointCut()")

public Object around(ProceedingJoinPoint point) throws Throwable {

long beginTime = System.currentTimeMillis();

//执行方法

Object result = point.proceed();

//执行时长(毫秒)

long time = System.currentTimeMillis() - beginTime;

//保存日志

saveSysLog(point, time);

return result;

}

private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {

MethodSignature signature = (MethodSignature) joinPoint.getSignature();

Method method = signature.getMethod();

Log sysLog = new Log();

sysLog.setTime(time);

SysLog syslog = method.getAnnotation(SysLog.class);

if (syslog != null) {

//注解上的描述

if (StrUtil.isNotBlank(syslog.value())) {

sysLog.setOperation(syslog.value());

}

if (StrUtil.isNotBlank(syslog.spelValue())) {

String spelValue = SpelUtil.generateKeyBySpEL(syslog.spelValue(), joinPoint);

sysLog.setOperation(spelValue);

}

}

//请求的方法名

String className = joinPoint.getTarget().getClass().getName();

String methodName = signature.getName();

sysLog.setMethod(className + "." + methodName + "()");

//请求的参数

Object[] args = joinPoint.getArgs();

try {

String params = jsONUtil.toJsonStr(args);

sysLog.setParams(params);

} catch (Exception e) {

}

//设置IP地址

sysLog.setIp(ServletUtil.getClientIP(request));

UserAgent ua = UserAgenhttp://tUtil.parse(request.getHeader("User-Agent"));

sysLog.setBrowser(ua.getBrowser().toString());

//保存系统日志

logService.create(sysLog);

}

}

4.方法上使用日志注解

@ApiOperation("高级搜索(包含点击1.热门列表 2.更多跳转页面)")

@PostMapping("searchData")

@SysLog(spelValue = "'高级搜索' + #searchVo.keyWord")

public ResponseEntity searchData(@RequestBody SearchVo searchVo) throws IOException {

SearchDto searchDto = searchService.searchData(searchVo);

return new ResponseEntity<>(searchDto, HttpStatus.OK);

}

@ApiOperation("登录授权")

@PostMapping("/login")

@SysLog("用户登录")

public ResponseEntity login(@Validated(User.Create.class) @RequestBody LoginUser loginUser) {

return ResponseEntity.ok(authInfo);

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:python中的字符串格式化(Python中字符串格式化)
下一篇:python中字典dict的操作技巧汇总(dict python用法)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~