实际项目怎么用到一些自定义接口呢?
一个注册功能就用了三个自定义接口,看下面代码
@NonRepeatable
@ApiVersion(ApiVersionHolder.V1_1_0)
@ControllerLog(description = "注册")
@RequestMapping("/register")
@ResponseBody
public Result register() {
LoginUserInfoResp info = userService.registerApp();
Map<String, Object> resp = new HashMap<String, Object>();
resp.put("user", info);
return Result.success(resp);
}
/**
* 标记接口不能重复请求
* 带这个注解的方法会缓存第一次请求的响应结果
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NonRepeatable {
}
@ApiVersion(ApiVersionHolder.V1_1_0)
/**
* 标识接口版本号
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface ApiVersion {
int value();
}
@ControllerLog(description = “注册”)
/**
* 自定义注解 拦截controller
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ControllerLog {
String description() default "";
}
这是上面的自定义注解创建好了,这时候可以使用到面向切面编程技术把它们使用上,每次看培训课都强调面向切面编程都会提到日志,我们前面@ControllerLog(description = “注册”)这个注解就是拿来做日志收集,表达不好代码来凑。其余两个用法我在以前开发过程中和下面用法差不多思路
@Aspect
@Component
public class SystemLogAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(SystemLogAspect.class);
private ThreadLocal<Long> startTimeLocal = new ThreadLocal<>();
/**
* 获取注解中对方法的描述信息 用于Controller层注解
*
* @param joinPoint 切点
* @return 方法描述
*/
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class<?> targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class<?>[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description = method.getAnnotation(SystemControllerLog.class).description();
break;
}
}
}
return description;
}
//Controller层, 日志记录切点
@Pointcut("@annotation(com.luogong.common.annotation.SystemControllerLog)")
public void controllerAspect() {
}
/**
* 前置通知 用于拦截Controller层记录用户的操作
*
* @param joinPoint 切点
*/
@Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) {
try {
startTimeLocal.set(System.currentTimeMillis());
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
LOGGER.info("*****************************************Controller Start:"
+ request.getRequestURI() + "*********************************************");
String methodName = (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName());
LOGGER.info("请求方法:" + methodName);
LOGGER.info("方法描述:" + getControllerMethodDescription(joinPoint));
//打印请求参数等信息
HttpUtils.logRequest(request);
} catch (Throwable e) {
LogUtils.printException(LOGGER, e, "执行前异常");
}
}
@After("controllerAspect()")
public void doAfter(JoinPoint joinPoint) {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String methodName = (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName());
LOGGER.trace(methodName + " : finished!" );
long end = System.currentTimeMillis();
long start = startTimeLocal.get();
LOGGER.info("*****************************************Controller End:"
+ request.getRequestURI()
+ ",cost:" + (end - start) + "ms" +
"********************************************");
} catch (Throwable e) {
LogUtils.printException(LOGGER, e, "执行后异常");
}
}
}