Spring AOP自定义注解实现日志管理

 元注解:

元注解就是可以加在注解上的注解,元注解不可以自定义。下面我来一一说明一下这四个元注解的作用。

@Documented

如果添加了@Documented,注解将能够在JavaDoc中展现。

@Retention

描述注解的生命周期,即什么时候注解是有效

类型说明
RetentionPolicy.SOURCE在源文件中有效
RetentionPolicy.CLASS在 class 文件中有效
RetentionPolicy.RUNTIME在运行时有效

@Inherited

是否允许子类继承该注解。即@Spongebob 如果修饰了类A,那么类A的子类类B也会默认被@Spongebob 修饰。

@Target

表示该注解用于什么地方。默认值为任何元素,表示该注解可以用于任何地方。注解值可以多选,如果建注解用到了未定义的地方,编译会报错。

类型说明
CONSTRUCTOR可用于描述构造器
FIELD用于描述域(属性)
LOCAL_VARIABLE用于描述局部变量
METHOD用于描述方法
PACKAGE用于描述包
PARAMETER

用于描述参数

TYPE用于描述类或接口(甚至 enum )

 接下来都是干货,新建自定义注解Log

ackage com.gpdi.operatingunit.common.annotation;

import java.lang.annotation.*;

/**
 * @Description: 系统日志注解
 * @Author: Lxq
 * @Date: 2019/10/21 11:20
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

    String value() default "";
}

新建LogAspect 日志切面出来类

package com.gpdi.operatingunit.common.aspect;

import com.google.gson.Gson;
import com.gpdi.operatingunit.common.annotation.Log;
import com.gpdi.operatingunit.entity.system.SysLog;
import com.gpdi.operatingunit.entity.system.SysUser;
import com.gpdi.operatingunit.service.system.SysLogService;
import com.gpdi.operatingunit.utils.HttpContextUtils;
import com.gpdi.operatingunit.utils.IPUtils;
import com.gpdi.operatingunit.utils.ShiroUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.lang.ProceedingJoinPoint;
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.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @Description:系统日志,切面处理类
 * @Author: Lxq
 * @Date: 2019/10/21 11:31
 */
@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysLogService sysLogService;

    // 自定义注解的位置
    @Pointcut("@annotation(com.gpdi.operatingunit.common.annotation.Log)")
    public void logPointCut() {

    }
    
    
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        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();
        Log log = method.getAnnotation(Log.class);
        if (log != null) {
            //注解上的描述
            sysLog.setOperType(log.value());
        }
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");

        //请求的参数
        Object[] args = joinPoint.getArgs();
        try {
            if ("用户登录".equals(log.value())) {
                //只保存第一个参数
                String params = new Gson().toJson(args[0]);
                sysLog.setParams(params);
            } else {
                //保存全部参数
                String params = new Gson().toJson(args);
                sysLog.setParams(params);
            }
        } catch (Exception e) {

        }
        //获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        //设置IP地址
        sysLog.setIp(IPUtils.getIpAddr(request));
        //用户名
        SysUser sysUser = ShiroUtils.getUser();
        sysLog.setUserId(sysUser.getId());
        sysLog.setExecuteTime(time);
        sysLog.setOperTime(new Date());
        //保存系统日志
        sysLogService.insert(sysLog);
    }
}

在方法中使用

    @Log("修改密码")
    @PostMapping("/updatePass")
    public R updateUserInfo(String pass){
        SysUser user = ShiroUtils.getUser();
        user.setSalt(getSalt());
        user.setPassword(new Sha256Hash(pass, user.getSalt(), 3).toString());
        user.setUpdateTime(new Date());
        sysUserMapper.updateById(user);
        return R.ok();
    }

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP是一种利用代理机制实现面向切面编程的框架。它可以通过自定义注解实现一些特定的逻辑。在Spring AOP中,我们可以通过在自定义注解上添加相关的切点表达式和通知方法来实现对目标方法的增强。这样可以实现一些横切关注点的统一处理,如记录系统日志、权限校验等。通过使用Spring AOP自定义注解,我们可以更加灵活地对代码进行管理和维护。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [spring aop 自定义注解保存操作日志到mysql数据库 源码](https://download.csdn.net/download/y_h_d/48993109)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Spring AOP 自定义注解实现代码](https://download.csdn.net/download/weixin_38714637/12781779)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [spring AOP自定义注解方式实现日志管理的实例讲解](https://download.csdn.net/download/weixin_38552536/12764634)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值