spring boot实现切面编程实现简单的切面。用log日志切面来进行举例。
1.定义注解的类
@Target({ElementType.PARAMETER,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
/**
* 描述
*/
String description() default "";
/**
* 方法类型 INSERT DELETE UPDATE OTHER
*/
MethodType methodType() default MethodType.OTHER;
}
2.定义切面类,切点@annotation的意思通过注解Log注解 进入切点
在这里插入代码片@Aspect
@Component
public class LogAspect {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
/**
* web层切点
* 1. @Pointcut("execution(public * com.astutephone.clouddesktop.zebra.modules.*.controller..*(..))") web层的所有方法
* 2. @Pointcut("@annotation(com.astutephone.clouddesktop.zebra.common.base.Log)") Log注解标注的方法
*/
@Pointcut("@annotation(com.astutephone.common.base.Log)")
public void webLog() {
}
/**
* 环绕通知
*/
@Around("webLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
//获取请求对象
HttpServletRequest request = getRequest();
WebLog webLog = new WebLog();
Object result = null;
try {
log.info("=================前置通知=====================");
long start = System.currentTimeMillis();
result = joinPoint.proceed();
log.info("=================返回通知=====================");
long timeCost = System.currentTimeMillis() - start;
// 获取Log注解
Log logAnnotation = getAnnotation(joinPoint);
// 封装webLog对象
// webLog.setMethodType(logAnnotation.methodType().name());
// webLog.setDescription(logAnnotation.description());
// webLog.setTimeCost((int) timeCost);
// webLog.setStartTime(start);
// webLog.setIpAddress(request.getRemoteAddr());
// webLog.setHttpMethod(request.getMethod());
// webLog.setParams(getParams(joinPoint));
// webLog.setResult(result);
// webLog.setUri(request.getRequestURI());
// webLog.setUrl(request.getRequestURL().toString());
// log.info("{}", JSON.toJSONString(webLog));
} catch (Throwable e) {
log.info("==================异常通知=====================");
log.error(e.getMessage());
throw new Throwable(e);
}finally {
log.info("=================后置通知=====================");
}
return result;
}
/**
* 获取方法上的注解
*/
private Log getAnnotation(ProceedingJoinPoint joinPoint) {
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
return method.getAnnotation(Log.class);
}
/**
* 获取参数
*/
private Object getParams(ProceedingJoinPoint joinPoint) {
// 参数名
String[] paramNames = getMethodSignature(joinPoint).getParameterNames();
// 参数值
Object[] paramValues = joinPoint.getArgs();
// 存储参数
Map<String, Object> params = new LinkedHashMap<>();
for (int i = 0; i < paramNames.length; i++) {
Object value = paramValues[i];
// MultipartFile对象以文件名作为参数值
if (value instanceof MultipartFile) {
MultipartFile file = (MultipartFile) value;
value = file.getOriginalFilename();
}
params.put(paramNames[i], value);
}
return params;
}
private MethodSignature getMethodSignature(ProceedingJoinPoint joinPoint) {
return (MethodSignature) joinPoint.getSignature();
}
private HttpServletRequest getRequest() {
ServletRequestAttributes requestAttributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return requestAttributes.getRequest();
}
}
3.方法上面加注解类的注解
@RequestMapping("/iplist")
@ApiOperation("iplist")
@com.astutephone.common.base.Log(description = "aaaa")
public JSONObject iplist(HttpServletRequest request) {
log.info("1111");
}