1.自定义注解
1.1自定义注解
@Target({ElementType.METHOD}) //此注解的作用目标
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented //标注作用
public @interface MyLog {
String method() default "";
}
1.2 使用该注解
@RestController
@RequestMapping("/myAnnotation")
public class TestController {
@GetMapping(value = "/myLog")
@MyLog(method = "调用say方法")
public String say(){
return "this is My Annotation";
}
}
2.注解与AOP结合使用
2.1定义一个注解
@Target({ElementType.METHOD}) //此注解的作用目标
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented //标注作用
public @interface MyLog {
String method() default "";
}
2.2定义一个切面(日志打印请求参数)
@Component
@Aspect //告诉spring这是一个切面
@Slf4j
public class MyLogAspect {
/**
* 定义一个切点,切点表达式:扫描TestController包下所有的类
*/
@Pointcut("execution(public * com.gpb.studyannotdtion.TestController..*(..))")
public void webLog(){}
/**
* 环绕通知方法(也可以前置通知,后置通知) 获取请求地址、请求方式 请求方法
* @param joinPoint 代理方法的信息对象
*/
@Around("webLog()")
public Object isWeblog(ProceedingJoinPoint joinPoint) throws Throwable {
//1.获取请求地址
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
String url = request.getRequestURL().toString();
log.info("请求地址:" + url);
//2.获取请求参数
Object[] args = joinPoint.getArgs();
StringBuilder params = new StringBuilder();
for (Object arg : args) {
if (null == arg){
continue;
}
params.append(args).append(",");
}
log.info("请求参数:"+ params);
//3.方法信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
String method1 = method.getAnnotation(MyLog.class).method();
log.info("调用的方法名称:"+method.getName() + "注解值:"+ method1);
//环绕通知需要有返回值,返回Controller的结果
return joinPoint.proceed();
}
3.注解实现重复提交(接口鉴权)
这里只是实现接口在规定时间内的多次提交,还可以实现接口的简单鉴权等功能
3.1.定义一个注解
@Target({ElementType.METHOD}) //此注解的作用目标
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented //标注作用
public @interface MyLog {
long expireTime() default 0L;
String method() default "";
}
3.2与AOP结合
/**
* 前绕通知与redis结合防止用户重复提交
* @param joinPoint
*/
@Before("webLog()")
public void again(ProceedingJoinPoint joinPoint) {
//防止用户在同一时间多次提交
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
long time = method.getAnnotation(MyLog.class).expireTime();
String name = method.getAnnotation(MyLog.class).method();
String key = method.getName() + name;
try {
if (redisTemplate.opsForValue().setIfAbsent(key, "lock", time, TimeUnit.MILLISECONDS)) {
//加锁成功,执行完业务逻辑删除锁
redisTemplate.delete(key);
}
} catch (Exception e) {
log.info("请勿重复提交");
} finally {
redisTemplate.delete(key);
}
}
3.3在controller的方法上使用该注解
@RestController
@RequestMapping("/myAnnotation")
public class TestController {
@GetMapping(value = "/myLog")
@MyLog(method = "调用say方法",expireTime = 3000L)
public String say(){
return "this is My Annotation";
}
}