- @documented //作用域
- @Inherited //是否可被子类继承
- @Target({ElementType.ANNOTATION_TYPE,ElementType.METHOD,ElementType.FIELD}) //适用范围
- @Retention(RetentionPolicy.RUNTIME) //是否在运行时被VM保留
适用案例: 登录校验
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface LoginInterceptorAnnotation {
}
public class SourceAccessInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入拦截器了");
HandlerMethod handlerMethod = (HandlerMethod)handler;
Method method = handlerMethod.getMethod();
LoginInterceptorAnnotation annotation = method.getAnnotation(LoginInterceptorAnnotation.class);
if(annotation == null){
System.out.println("不需要登录校验");
return true;
}
Map<String, String[]> parameterMap = request.getParameterMap();
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("进入拦截器了2");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("进入拦截器了3");
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@Configuration
public class InterceptorTrainConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SourceAccessInterceptor()).addPathPatterns("/**");
}
}
@RequestMapping(value = "/hello",method = {RequestMethod.GET})
@ResponseBody
@LoginInterceptorAnnotation
public String getMethodName(String sellerId) {
return "lhy_test";
}
适用案例: 打印方法日志
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface MyLogAnnotation {
}
@Aspect
@Component
public class LogAspect {
@Pointcut(value = "@annotation(com.lhy.logininterceptor.MyLogAnnotation)")
public void logPointCut(){}
@Around(value = "logPointCut()")
public void pointCutAround(ProceedingJoinPoint point){
String methodName = point.getSignature().getName();
Object[] param = point.getArgs();
StringBuilder sb = new StringBuilder();
for(Object o : param){
sb.append(o).append("; ");
}
long timeMillis = System.currentTimeMillis();
try {
System.out.println("开始执行方法");
Object proceed = point.proceed();
System.out.println(proceed);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("进入[" + methodName + "]方法,参数为:" + sb.toString()+" 方法总耗时:"+(System.currentTimeMillis()-timeMillis));
System.out.println(methodName + "方法执行结束");
}
}
@RequestMapping(value = "/hello2",method = {RequestMethod.GET})
@ResponseBody
@MyLogAnnotation
public String getMethodLog(String sellerId) {
return "cwp_test";
}
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@Aspect
public class ServiceAspect {
private static final Logger bizServiceLogger = LoggerFactory.getLogger("bizServiceLog");
private static final Logger bizParamLogger = LoggerFactory.getLogger("bizParamLog");
private static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final String LOG_DELIMITER = "|";
private static final String APP_NAME = "app";
private final AtomicInteger count = new AtomicInteger(0);
@Around("execution(* com.api.facade..*.*(..))")
public Object doAroundMethod(ProceedingJoinPoint pig) throws Throwable {
Object obj = null;
long startTime = System.currentTimeMillis();
try {
this.before(pig);
obj = pig.proceed();
} catch (Throwable e) {
long endTime = System.currentTimeMillis();
bizServiceLogger.error("aop is Exception " + ExceptionUtils.getStackTrace(e));
printBizServiceLog(pig, obj, endTime - startTime);
throw e;
}
long endTime = System.currentTimeMillis();
try {
printBizServiceLog(pig, obj, endTime - startTime);
} catch (Exception e) {
bizServiceLogger.error("print aopBizLog error", e);
}
return obj;
}
private void before(ProceedingJoinPoint pig) {
Method method = ((MethodSignature) pig.getSignature()).getMethod();
List<String> inParams = formatParams(pig, method);
String aopMethodArgsLimit = OpenCloseSwitch.aopMethodArgsLimit;
boolean contains = aopMethodArgsLimit.contains(method.getName());
if (MtopContext.getApi() != null) {
String mtopApi = MtopContext.getApi();
if (contains || !OpenCloseSwitch.aopParamLog) {
bizParamLogger.debug(String.format("API_Name:[%s], MethodName:[%s.%s],TraceId:[%s], MethodArgs:[%s]",
mtopApi,
pig.getTarget().getClass().getSimpleName(),
method.getName(),
EagleEye.getTraceId(),
StringUtils.join(inParams, ",")));
} else {
bizParamLogger.info(String.format("API_Name:[%s], MethodName:[%s.%s],TraceId:[%s], MethodArgs:[%s]",
mtopApi,
pig.getTarget().getClass().getSimpleName(),
method.getName(),
EagleEye.getTraceId(),
StringUtils.join(inParams, ",")));
}
} else {
if (contains || !OpenCloseSwitch.aopParamLog) {
bizParamLogger.debug(String.format("MethodName:[%s.%s],TraceId:[%s], MethodArgs:[%s]",
pig.getTarget().getClass().getSimpleName(),
method.getName(),
EagleEye.getTraceId(),
StringUtils.join(inParams, ",")));
} else {
bizParamLogger.info(String.format("MethodName:[%s.%s],TraceId:[%s], MethodArgs:[%s]",
pig.getTarget().getClass().getSimpleName(),
method.getName(),
EagleEye.getTraceId(),
StringUtils.join(inParams, ",")));
}
}
}
private List<String> formatParams(ProceedingJoinPoint pig, Method method) {
Object[] args = pig.getArgs();
List<String> paramList = new ArrayList<String>();
try {
Parameter[] parameters = pig.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes()).getParameters();
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse || args[i] instanceof MultipartFile || args[i] instanceof ServletServerHttpRequest || args[i] instanceof ServletServerHttpResponse) {
continue;
}
paramList.add(parameters[i].getName() + ":" + JSONObject.toJSONString(args[i]));
}
} catch (Exception e) {
bizServiceLogger.error("aop formatParams is error", e);
}
return paramList;
}
private void printBizServiceLog(ProceedingJoinPoint pig, Object resultObj, long costTime) {
StringBuilder sb = new StringBuilder();
String simpleClassName = pig.getTarget().getClass().getSimpleName();
Method method = ((MethodSignature) pig.getSignature()).getMethod();
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
String ip = getHostIp();
sb.append(LOG_DELIMITER).append("bizServiceLog");
sb.append(LOG_DELIMITER).append(dateFormatter.format(new Date()));
sb.append(LOG_DELIMITER).append(EagleEye.getTraceId());
sb.append(LOG_DELIMITER).append(EagleEye.getRpcId());
sb.append(LOG_DELIMITER).append(APP_NAME);
sb.append(LOG_DELIMITER).append(simpleClassName);
sb.append(LOG_DELIMITER).append(methodName);
sb.append(LOG_DELIMITER).append(costTime);
Result result = convertResult(resultObj);
sb.append(LOG_DELIMITER).append(result.isSuccess());
sb.append(LOG_DELIMITER).append(result.isSuccess() ? "success" : result.getErrorCode());
sb.append(LOG_DELIMITER).append(result.isSuccess() ? "success" : result.getErrorMsg());
sb.append(LOG_DELIMITER).append("1".equals(EagleEye.getUserData("t")) ? "1" : "0");
sb.append(LOG_DELIMITER).append(ip);
sb.append(LOG_DELIMITER).append(count);
if (!OpenCloseSwitch.aopLog) {
bizServiceLogger.debug(sb.toString());
} else {
bizServiceLogger.info(sb.toString());
}
}
private Result convertResult(Object resultObj) {
Result result = new Result();
if (resultObj == null) {
result.setSuccess(false);
result.setErrorCode(ServiceCode.AOP_EXCEPTION.getCode());
result.setErrorMsg(ServiceCode.AOP_EXCEPTION.getMsg());
return result;
}
if (resultObj instanceof Result) {
return (Result) resultObj;
}
result.setSuccess(true);
result.setErrorCode(ServiceCode.AOP_NOT_EXIST_RESULT.getCode());
result.setErrorMsg(ServiceCode.AOP_NOT_EXIST_RESULT.getMsg());
return result;
}