国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

石家莊網(wǎng)站開發(fā)設(shè)計(jì)百度網(wǎng)站下載

石家莊網(wǎng)站開發(fā)設(shè)計(jì),百度網(wǎng)站下載,做網(wǎng)站讓人來注冊,做網(wǎng)站寫概要設(shè)計(jì)Spring之Aop切面---日志收集(環(huán)繞處理、前置處理方式)--使用/教程/實(shí)例 簡介系統(tǒng)登錄日志類LoginLogEntity .java 一、環(huán)繞處理方式1、自定義注解類LoginLogAop.class2、切面處理類LogoutLogAspect.java 二、前置處理方式:1、自定義注解類Log…

Spring之Aop切面---日志收集(環(huán)繞處理、前置處理方式)--使用/教程/實(shí)例

    • 簡介
      • 系統(tǒng)登錄日志類LoginLogEntity .java
    • 一、環(huán)繞處理方式
      • 1、自定義注解類LoginLogAop.class
      • 2、切面處理類LogoutLogAspect.java
    • 二、前置處理方式:
      • 1、自定義注解類LogoutLogAop.class
      • 2、切面處理類LogoutLogAspect.java
    • 三、Proceedingjoinpoint簡述

簡介

本文章介紹采用兩種不同方式處理----系統(tǒng)登錄、系統(tǒng)退出登錄兩種場景日志。

  • 環(huán)繞處理系統(tǒng)登錄日志
  • 前置處理系統(tǒng)退出登錄日志

系統(tǒng)登錄日志類LoginLogEntity .java

package com.fy.test.entity;import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;import java.io.Serializable;
import java.time.LocalDateTime;import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;/*** @ClassName: LoginLogEntity * @Description: * @Author fy* @Date 2023/07/10 9:00*/
@Data
@Accessors(chain = true)
@TableName("t_login_log")
public class LoginLogEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 主鍵*/@TableId(value = "id", type = IdType.ASSIGN_ID)private String id;/*** 操作系統(tǒng)*/private String opOs;/*** 瀏覽器類型*/private String opBrowser;/*** 登錄IP地址*/private String opIp;/*** 登錄時(shí)間*/private LocalDateTime opDate;/*** 登錄用戶ID*/private String userId;/*** 登錄用戶名稱*/private String userName;/*** 錯(cuò)誤類型*/private String exCode;/*** 錯(cuò)誤信息*/private String exMsg;/*** 登錄狀態(tài)*/private boolean status;/*** 描述*/private String desc;
}

一、環(huán)繞處理方式

1、自定義注解類LoginLogAop.class

package com.fy.test.log.annotation;import java.lang.annotation.*;/*** @ClassName: LoginLogAop* @Description: * @Author fy* @Date 2023/07/10 9:05*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginLogAop {/*** 描述*/String desc() default "";}

2、切面處理類LogoutLogAspect.java

package com.fy.test.log.aspect;import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.fy.test.log.annotation.LoginLogAop;
import com.fy.test.utils.RequestHolder;
import com.fy.test.utils.SecurityUtil;
import com.fy.test.service.dto.LoginLogDto;
import com.fy.test.service.feign.LogServiceFeign;
import com.fy.test.service.vo.UserVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
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.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;/*** @ClassName: LoginLogAspect* @Description:* @Author fy* @Date 2023/07/10 9:05*/
@Slf4j
@Aspect
public class LoginLogAspect {@Autowiredprivate LogServiceFeign logServiceFeign;/*** 配置織入點(diǎn)*/@Pointcut("@annotation(com.fy.test.common.log.annotation.LoginLogAop)")public void logPointCut() {}/*** 通知方法會(huì)將目標(biāo)方法封裝起來* 注意:環(huán)繞方式選擇ProceedingJoinPoint* Proceedingjoinpoint 繼承了JoinPoint,在JoinPoint的基礎(chǔ)上暴露出 proceed(), 這個(gè)方法是AOP代理鏈執(zhí)行的方法。* JoinPoint僅能獲取相關(guān)參數(shù),無法執(zhí)行連接點(diǎn)。* 暴露出proceed()這個(gè)方法,就能支持 aop:around 這種切面(而其他的幾種切面只需要用到JoinPoint,這跟切面類型有關(guān)),* 就能控制走代理鏈還是走自己攔截的其他邏輯。  * * @param joinPoint 切點(diǎn)*/@Around(value = "logPointCut()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {Object result = joinPoint.proceed();LoginLogDto logDto = getLog();logDto.setStatus(true);handleLog(joinPoint, logDto);return result;}/*** 通知方法會(huì)在目標(biāo)方法拋出異常后執(zhí)行** @param joinPoint* @param e*/@AfterThrowing(value = "logPointCut()", throwing = "e")public void doAfterThrowing(JoinPoint joinPoint, Exception e) {LoginLogDto logDto = getLog();logDto.setExCode(e.getClass().getSimpleName()).setExMsg(e.getMessage());logDto.setStatus(false);handleLog(joinPoint, logDto);}private LoginLogDto getLog() {HttpServletRequest request = RequestHolder.getHttpServletRequest();UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));LoginLogDto loginLog = new LoginLogDto();loginLog.setOpIp(ServletUtil.getClientIP(request)).setOpOs(userAgent.getOs().getName()).setOpBrowser(userAgent.getBrowser().getName()).setUserId(SecurityUtil.getUserId()).setUserName(SecurityUtil.getUserName()).setOpDate(LocalDateTime.now());return loginLog;}protected void handleLog(final JoinPoint joinPoint, LoginLogDto loginLogDto) {// 獲得注解LoginLogAop logAop = getAnnotationLog(joinPoint);if (null == logAop) {return;}loginLogDto.setDescription(logAop.description());Map<String, Object> requestParams = getRequestParams(joinPoint);if (requestParams.containsKey("userVo")) {UserVo userVo = JSONObject.parseObject(JSON.toJSONString(requestParams.get("userVo")), UserVo.class);if (null != userVo && StringUtils.isBlank(loginLogDto.getUserName())) {loginLogDto.setUserName(userVo.getUsername());}}// 保存數(shù)據(jù)庫logServiceFeign.saveLoginLog(loginLogDto);}/*** 是否存在注解,如果存在就獲取*/private LoginLogAop getAnnotationLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();if (method != null) {return method.getAnnotation(LoginLogAop.class);}return null;}/*** 獲取入?yún)?/private Map<String, Object> getRequestParams(JoinPoint joinPoint) {Map<String, Object> requestParams = new HashMap<>();// 參數(shù)名String[] paramNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();// 參數(shù)值Object[] paramValues = joinPoint.getArgs();for (int i = 0; i < paramNames.length; i++) {Object value = paramValues[i];// 如果是文件對(duì)象if (value instanceof MultipartFile) {MultipartFile file = (MultipartFile) value;// 獲取文件名value = file.getOriginalFilename();}requestParams.put(paramNames[i], value);}return requestParams;}
}

二、前置處理方式:

1、自定義注解類LogoutLogAop.class

package com.fy.test.log.annotation;import java.lang.annotation.*;/*** @ClassName: LogoutLogAop* @Description: * @Author fy* @Date 2023/07/10 9:10*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogoutLogAop {/*** 描述*/String desc() default "";}

2、切面處理類LogoutLogAspect.java

package com.fy.test.log.aspect;import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.fy.test.log.annotation.LoginLogAop;
import com.fy.test.log.annotation.LogoutLogAop;
import com.fy.test.utils.RequestHolder;
import com.fy.test.utils.SecurityUtil;
import com.fy.test.service.dto.LoginLogDto;
import com.fy.test.service.feign.LogServiceFeign;
import com.fy.test.service.vo.UserVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;/*** @ClassName: LogoutLogAspect* @Description:* @Author fy* @Date 2023/07/10 9:10*/
@Slf4j
@Aspect
public class LogoutLogAspect {@Autowiredprivate LogServiceFeign logServiceFeign;/*** 配置織入點(diǎn)*/@Pointcut("@annotation(com.fy.test.log.annotation.LogoutLogAop)")public void logPointCut() {}/*** 通知方法會(huì)將目標(biāo)方法封裝起來** @param joinPoint 切點(diǎn)*/@Before("logPointCut()")public void doBefore(JoinPoint joinPoint) throws Throwable {try {System.out.println("==============前置處理開始==============");LoginLogDto logDto = getLog();logDto.setStatus(true);handleLog(joinPoint, logDto);} catch (Exception e) {//記錄本地異常日志log.error("==前置通知異常==");log.error("異常信息:{}", e.getMessage());}}/*** 通知方法會(huì)在目標(biāo)方法拋出異常后執(zhí)行** @param joinPoint* @param e*/@AfterThrowing(value = "logPointCut()", throwing = "e")public void doAfterThrowing(JoinPoint joinPoint, Exception e) {LoginLogDto logDto = getLog();logDto.setExCode(e.getClass().getSimpleName()).setExMsg(e.getMessage());logDto.setStatus(false);handleLog(joinPoint, logDto);}private LoginLogDto getLog() {HttpServletRequest request = RequestHolder.getHttpServletRequest();UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));LoginLogDto loginLogDto = new LoginLogDto();loginLogDto.setOpIp(ServletUtil.getClientIP(request)).setOpOs(userAgent.getOs().getName()).setOpBrowser(userAgent.getBrowser().getName()).setUserId(SecurityUtil.getUserId()).setUserName(SecurityUtil.getUserName()).setOpDate(LocalDateTime.now());return loginLogDto;}protected void handleLog(final JoinPoint joinPoint, LoginLogDto loginLogDto) {// 獲得注解LogoutLogAop logAop = getAnnotationLog(joinPoint);if (null == logAop) {return;}loginLogDto.setDesc(logAop.desc());// 保存數(shù)據(jù)庫logServiceFeign.saveLoginLog(loginLogDto);}/*** 是否存在注解,如果存在就獲取*/private LogoutLogAop getAnnotationLog(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();MethodSignature methodSignature = (MethodSignature) signature;Method method = methodSignature.getMethod();if (method != null) {return method.getAnnotation(LogoutLogAop.class);}return null;}/*** 獲取入?yún)?/private Map<String, Object> getRequestParams(JoinPoint joinPoint) {Map<String, Object> requestParams = new HashMap<>();// 參數(shù)名String[] paramNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();// 參數(shù)值Object[] paramValues = joinPoint.getArgs();for (int i = 0; i < paramNames.length; i++) {Object value = paramValues[i];// 如果是文件對(duì)象if (value instanceof MultipartFile) {MultipartFile file = (MultipartFile) value;// 獲取文件名value = file.getOriginalFilename();}requestParams.put(paramNames[i], value);}return requestParams;}
}

三、Proceedingjoinpoint簡述

Proceedingjoinpoint 繼承了JoinPoint,在JoinPoint的基礎(chǔ)上暴露出 proceed(), 這個(gè)方法是AOP代理鏈執(zhí)行的方法。

JoinPoint僅能獲取相關(guān)參數(shù),無法執(zhí)行連接點(diǎn)。暴露出proceed()這個(gè)方法,就能支持 aop:around 這種切面(而其他的幾種切面只需要用到JoinPoint,這跟切面類型有關(guān)),就能控制走代理鏈還是走自己攔截的其他邏輯。

import org.aspectj.lang.reflect.SourceLocation;  
public interface JoinPoint {  String toString();         //連接點(diǎn)所在位置的相關(guān)信息  String toShortString();    //連接點(diǎn)所在位置的簡短相關(guān)信息  String toLongString();     //連接點(diǎn)所在位置的全部相關(guān)信息  Object getThis();          //返回AOP代理對(duì)象,也就是com.sun.proxy.$Proxy18Object getTarget();        //返回目標(biāo)對(duì)象,一般我們都需要它或者(也就是定義方法的接口或類,為什么會(huì)是接口呢?//這主要是在目標(biāo)對(duì)象本身是動(dòng)態(tài)代理的情況下,例如Mapper。所以返回的是定義方法的對(duì)象如//aoptest.daoimpl.GoodDaoImpl或com.b.base.BaseMapper<T, E, PK>)Object[] getArgs();        //返回被通知方法參數(shù)列表  Signature getSignature();  //返回當(dāng)前連接點(diǎn)簽名。其getName()方法返回方法的FQN,如void aoptest.dao.GoodDao.delete()//或com.b.base.BaseMapper.insert(T)(需要注意的是,很多時(shí)候我們定義了子類繼承父類的時(shí)候,//我們希望拿到基于子類的FQN,無法直接拿到,要依賴于//AopUtils.getTargetClass(point.getTarget())獲取原始代理對(duì)象,下面會(huì)詳細(xì)講解)SourceLocation getSourceLocation();//返回連接點(diǎn)方法所在類文件中的位置  String getKind();           //連接點(diǎn)類型  StaticPart getStaticPart(); //返回連接點(diǎn)靜態(tài)部分  }  public interface ProceedingJoinPoint extends JoinPoint {  public Object proceed() throws Throwable;  public Object proceed(Object[] args) throws Throwable;  }

JoinPoint.StaticPart:提供訪問連接點(diǎn)的靜態(tài)部分,如被通知方法簽名、連接點(diǎn)類型等等。

public interface StaticPart {  Signature getSignature();    //返回當(dāng)前連接點(diǎn)簽名  String getKind();            //連接點(diǎn)類型  int getId();                 //唯一標(biāo)識(shí)  String toString();           //連接點(diǎn)所在位置的相關(guān)信息  String toShortString();      //連接點(diǎn)所在位置的簡短相關(guān)信息  String toLongString();       //連接點(diǎn)所在位置的全部相關(guān)信息  
}
http://m.aloenet.com.cn/news/44157.html

相關(guān)文章:

  • 做甜品網(wǎng)站的需求分析網(wǎng)站如何發(fā)布
  • 如何給網(wǎng)站做流量百度推廣網(wǎng)址是多少
  • 網(wǎng)站域名使用費(fèi)多少網(wǎng)絡(luò)營銷與直播電商學(xué)什么
  • 武漢電商網(wǎng)站建設(shè)sem是什么設(shè)備
  • 世界十大建筑設(shè)計(jì)公司排名外鏈seo推廣
  • 廣東裝飾公司網(wǎng)站建設(shè)防惡意競價(jià)點(diǎn)擊軟件
  • wordpress做資源下載站網(wǎng)站宣傳的方法有哪些
  • 青海省建設(shè)廳官方網(wǎng)站百度賬號(hào)注冊平臺(tái)
  • 水果網(wǎng)站策劃書百度站長資源
  • 廈門網(wǎng)站排名優(yōu)化費(fèi)用百度網(wǎng)盤鏈接
  • 如何請(qǐng)人做網(wǎng)站爆款采集推廣引流軟件
  • 圖片站wordpress網(wǎng)站推廣優(yōu)化排名
  • 騰云建站靠譜嗎什么是網(wǎng)站
  • WordPress生成電商小程序南昌seo教程
  • 域名申請(qǐng)到網(wǎng)站建設(shè)教程廣告銷售如何尋找客戶
  • 怎么選擇企業(yè)建站公司網(wǎng)站關(guān)鍵字優(yōu)化價(jià)格
  • 個(gè)人網(wǎng)站 名字百度智能云建站
  • 做百度網(wǎng)站一般多少錢搜索引擎分析論文
  • 秦皇島優(yōu)化營商環(huán)境北京網(wǎng)站優(yōu)化服務(wù)商
  • 唐山直銷系統(tǒng)開發(fā)關(guān)鍵詞seo深圳
  • 網(wǎng)站建設(shè)的市場需求網(wǎng)站維護(hù)
  • 免費(fèi)建網(wǎng)站哪個(gè)好站長工具seo綜合查詢工具
  • 煙臺(tái)建設(shè)集團(tuán)網(wǎng)站愛鏈接外鏈購買
  • 做互聯(lián)網(wǎng)網(wǎng)站賺錢嗎seo關(guān)鍵詞推廣渠道
  • 中小企業(yè)門戶網(wǎng)站建設(shè)策略北海seo快速排名
  • 云南城鄉(xiāng)建設(shè)網(wǎng)站如何自己創(chuàng)建網(wǎng)址
  • 網(wǎng)站的相關(guān)鏈接怎么做濟(jì)南seo網(wǎng)絡(luò)優(yōu)化公司
  • wordpress軟件下載源碼搜索引擎優(yōu)化的名詞解釋
  • 網(wǎng)站建設(shè)銷售實(shí)習(xí)報(bào)告臨沂網(wǎng)站建設(shè)
  • 什么平臺(tái)引流最快太原seo網(wǎng)絡(luò)優(yōu)化招聘網(wǎng)