需求:统计研发测试云各个功能使用情况,即各项目下各个功能调用次数的统计
初步解决方案:使用SpringAOP切面思想,自定义个注解,将注解放在关键接口上,以这个接口为切入点,当调用具有此注解的接口时对方法进行拦截,获取方法上的RequestMapping或者PostMapping等注解的属性值进行统计。
package com.haiyisoft.cloud.devops.util;import com.haiyisoft.cloud.devops.web.util.UserViewUtil;import com.haiyisoft.cloud.jpa.util.JPAUtil;import com.haiyisoft.cloud.mservice.util.CommonUtil;import com.haiyisoft.cloud.mservice.util.SequenceUtil;import com.haiyisoft.cloud.web.annotation.PrimaryAccess;import com.haiyisoft.cloud.web.annotation.ProjectMapping;import com.haiyisoft.entity.devops.AccessInterface;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.Signature;import org.aspectj.lang.annotation.*;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.stereotype.Component;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.lang.reflect.Method;import java.util.*;/*** @author seanwang* @version 1.0* @date 2021/3/1 15:22* 接口访问记录统计。*/@Component@Aspectpublic class InterfaceAccessHandler{/*** 定义切面* Pointcut("execution(* com.haiyisoft.cloud.*.*.controller..*.*(..))")* com.haiyisoft.cloud.devops.*.controller包及其子包下的所有接口都会被统计*/@Pointcut("@annotation(com.haiyisoft.cloud.web.annotation.PrimaryAccess)")public void pointCut(){}/*** 在接口原有的方法执行前,将会首先执行此处的代码*/@Before("pointCut()")public void doBefore(JoinPoint joinPoint) {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String projectIdStr = request.getParameter("projectId");Long projectId = null;if (projectIdStr != null){projectId = Long.parseLong(projectIdStr);}//记录请求信息Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();String value = "";String name = "";if (method.isAnnotationPresent(RequestMapping.class)) {RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);value = Arrays.toString(requestMapping.value());name = requestMapping.name();}else if (method.isAnnotationPresent(GetMapping.class)) {GetMapping getMapping = method.getAnnotation(GetMapping.class);value = Arrays.toString(getMapping.value());name = getMapping.name();}else if (method.isAnnotationPresent(PostMapping.class)) {PostMapping postMapping = method.getAnnotation(PostMapping.class);value = Arrays.toString(postMapping.value());name = postMapping.name();}else if (method.isAnnotationPresent(ProjectMapping.class)) {ProjectMapping projectMapping = method.getAnnotation(ProjectMapping.class);value = Arrays.toString(projectMapping.value());name = projectMapping.name();}else if (method.isAnnotationPresent(PrimaryAccess.class)) {PrimaryAccess primaryAccess = method.getAnnotation(PrimaryAccess.class);value = primaryAccess.accessInterface();name = primaryAccess.desc();}//持久化collect(value,name,projectId);}private void collect(String interfaceName, String interfaceDesc, Long projectId) {AccessInterface accessInterface = new AccessInterface();accessInterface.setAccessId(SequenceUtil.genEntitySequenceNo(AccessInterface.class));accessInterface.setInterfaceUrl(formatUrl(interfaceName));accessInterface.setInterfaceDesc(interfaceDesc);accessInterface.setAccessTime(CommonUtil.getDateTime());accessInterface.setProjectId(projectId);try {accessInterface.setAccessUser(UserViewUtil.getUserName());}catch (NullPointerException e){}JPAUtil.create(accessInterface);}/*** [/getNoticeCount] ==> /getNoticeCount*/private String formatUrl(String url) {return url.substring(1,url.length()-1);}}
