springboot aop 記錄使用者操作記錄
阿新 • • 發佈:2018-12-20
採用方案: 使用spring 的 aop 技術切到自定義註解上,針對不同註解標誌進行引數解析,記錄日誌 缺點是要針對每個不同的註解標誌進行分別取註解標誌,獲取引數進行日誌記錄輸出
1. 需要引用的依賴
<!--spring切面aop依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 在application.properties檔案里加這樣一條配置 spring.aop.auto=true //這個配置我的例子中沒有加 也正常執行
2. 建立實體類
public class SysLog implements Serializable { private Long id; private String username; //使用者名稱 private String operation; //操作 private String method; //方法名 private String params; //引數 private String ip; //ip地址 private Date createDate; //操作時間 //建立getter和setter方法 }
3. 使用spring 的 aop 技術切到自定義註解上,所以先建立一個自定義註解類
import java.lang.annotation.*;
/**
* 自定義註解類
*/
@Target(ElementType.METHOD) //註解放置的目標位置,METHOD是可註解在方法級別上
@Retention(RetentionPolicy.RUNTIME) //註解在哪個階段執行
@Documented //生成文件
public @interface MyLog {
String value() default "";
}
4. 建立aop切面實現類
import com.alibaba.fastjson.JSON; import com.qfedu.rongzaiboot.annotation.MyLog; import com.qfedu.rongzaiboot.entity.SysLog; import com.qfedu.rongzaiboot.service.SysLogService; import com.qfedu.rongzaiboot.utils.HttpContextUtils; import com.qfedu.rongzaiboot.utils.IPUtils; import com.qfedu.rongzaiboot.utils.ShiroUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Date; /** * 系統日誌:切面處理類 */ @Aspect @Component public class SysLogAspect { @Autowired private SysLogService sysLogService; //定義切點 @Pointcut //在註解的位置切入程式碼 @Pointcut("@annotation( com.qfedu.rongzaiboot.annotation.MyLog)") public void logPoinCut() { } //切面 配置通知 @AfterReturning("logPoinCut()") public void saveSysLog(JoinPoint joinPoint) { System.out.println("切面。。。。。"); //儲存日誌 SysLog sysLog = new SysLog(); //從切面織入點處通過反射機制獲取織入點處的方法 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //獲取切入點所在的方法 Method method = signature.getMethod(); //獲取操作 MyLog myLog = method.getAnnotation(MyLog.class); if (myLog != null) { String value = myLog.value(); sysLog.setOperation(value);//儲存獲取的操作 } //獲取請求的類名 String className = joinPoint.getTarget().getClass().getName(); //獲取請求的方法名 String methodName = method.getName(); sysLog.setMethod(className + "." + methodName); //請求的引數 Object[] args = joinPoint.getArgs(); //將引數所在的陣列轉換成json String params = JSON.toJSONString(args); sysLog.setParams(params); sysLog.setCreateDate(new Date()); //獲取使用者名稱 sysLog.setUsername(ShiroUtils.getUserEntity().getUsername()); //獲取使用者ip地址 HttpServletRequest request = HttpContextUtils.getHttpServletRequest(); sysLog.setIp(IPUtils.getIpAddr(request)); //呼叫service儲存SysLog實體類到資料庫 sysLogService.save(sysLog); } }
5. 接下來就可以在需要監控的方法上新增 aop的自定義註解
格式為 @+自定義註解的類名 @MyLog
//例如在contoller類的方法上加註解
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController extends AbstractController {
@Autowired
private SysMenuService sysMenuService;
@MyLog(value = "刪除選單記錄") //這裡添加了AOP的自定義註解
@PostMapping("/del")
public R deleteBatch(@RequestBody Long[] menuIds) {
for (Long menuId : menuIds) {
if (menuId <= 31) {
return R.error("系統選單,不能刪除");
}
}
sysMenuService.deleteBatch(menuIds);
return R.ok("刪除成功");
}
}