1,AOP簡介
面相切面編程(AOP)卢厂,可以實現(xiàn)例如日志打印、身份認(rèn)證惠啄,權(quán)限管理慎恒,安全監(jiān)測。
AOP的實現(xiàn)原理是基于動態(tài)代理(Dynamic Proxy)的機(jī)制撵渡。
本文以操作日志保存為例融柬,主要是介紹通過自定義注解,靈活配置方法是否使用切面趋距,比如身份認(rèn)證粒氧,通過增加注解,可以指定那些方法需要身份認(rèn)證棚品,實現(xiàn)更靈活使用AOP靠欢。
2廊敌,創(chuàng)建注解
import java.lang.annotation.*;
/**
* 系統(tǒng)日志注解
*
* @author Aiot_QJ
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default "";
}
3铜跑,日志切面
/**
* 系統(tǒng)日志,切面處理類
* @author Aiot_QJ
*/
@Aspect
@Component
public class SysLogAspect {
@Autowired
private SysLogService sysLogService;
@Pointcut("@annotation(SysLog)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
//執(zhí)行方法
Object result = point.proceed();
//執(zhí)行時長(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveSysLog(point, time);
return result;
}
private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
SysLog sysLog = new SysLog();
com.pcidata.common.annotation.SysLog syslog = method.getAnnotation(com.pcidata.common.annotation.SysLog.class);
if(syslog != null){
//注解上的描述
sysLog.setOperation(syslog.value());
}
//請求的方法名
String className = joinPoint.getTarget().getClass().getName();
String methodName = signature.getName();
sysLog.setMethod(className + "." + methodName + "()");
//請求的參數(shù)
Object[] args = joinPoint.getArgs();
try{
String params = new Gson().toJson(args[0]);
sysLog.setParams(params);
}catch (Exception e){
}
//獲取request
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//設(shè)置IP地址
sysLog.setIp(IPUtils.getIpAddr(request));
//用戶名
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();
sysLog.setUsername(username);
sysLog.setTime(time);
sysLog.setCreateDate(new Date());
//保存系統(tǒng)日志
sysLogService.insert(sysLog);
}
}
4骡澈,接口使用
@SysLog("hello world")
@RequestMapping("/hello")
public String hello(@RequestBody String msg){
return "hello world"+msg;
}
總結(jié)
通過SpringAOP+注解锅纺,可以靈活記錄重要接口的日志信息到數(shù)據(jù)庫,方便進(jìn)行日志分析和統(tǒng)計肋殴。