自定义注解,使用切面(Aspect)记录操作日志

1、注解的生命周期

注解的生命周期有 3 种策略,定义在 RetentionPolicy 枚举中。

1)SOURCE:在源文件中有效,被编译器丢弃。

2)CLASS:在编译器生成的字节码文件中有效,但在运行时会被处理类文件的 JVM 丢弃。

3)RUNTIME:在运行时有效。这也是注解生命周期中最常用的一种策略,它允许程序通过反射的方式访问注解,并根据注解的定义执行相应的代码。

2、注解装饰的目标

注解的目标定义了注解将适用于哪一种级别的 Java 代码上,有些注解只适用于方法,有些只适用于成员变量,有些只适用于类,有些则都适用。

截止到 Java 9,注解的类型一共有 11 种,定义在 ElementType 枚举中。

1)TYPE:用于类、接口、注解、枚举

2)FIELD:用于字段(类的成员变量),或者枚举常量

3)METHOD:用于方法

4)PARAMETER:用于普通方法或者构造方法的参数

5)CONSTRUCTOR:用于构造方法

6)LOCAL_VARIABLE:用于变量

7)ANNOTATION_TYPE:用于注解

8)PACKAGE:用于包

9)TYPE_PARAMETER:用于泛型参数

10)TYPE_USE:用于声明语句、泛型或者强制转换语句中的类型

11)MODULE:用于模块

import java.lang.annotation.*;

/**
 * 操作日志注解
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {

    /**
     * 记录操作描述
     *
     * @return
     */
    String remark() default "";

    /**
     * LogTypeFinal中定义的常量
     *
     * @return
     */
    String openType() default "";

    String mkbh() default "";

    String qqurl() default "";
}

 切面编程:

import com.alibaba.fastjson.JSONObject;
import com.sky.common.util.UserUtil;
import com.sky.service.log.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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


@Aspect
@Component
public class SystemLogAspect {

    private static final Logger logger = LoggerFactory.getLogger(SystemLogAspect.class);

    @Pointcut("@annotation(com.sky.rxyWeb.log.MethodLog)")
    public void logAspect() {
    }


    @Autowired
    HttpServletRequest request;

    @Autowired
    LogService logService;

    /**
     * 前置通知
     *
     * @param joinPoint
     */
    @Before("logAspect()")
    public void doBefore(JoinPoint joinPoint) {
    }

    /**
     * 后置通知
     *
     * @param joinPoint
     */
    @After("logAspect()")
    public void doAfter(JoinPoint joinPoint) {
    }

    /**
     * 后置返回通知
     *
     * @param joinPoint
     */
    @AfterReturning(value = "logAspect()", returning = "result")
    public void doAfterReturn(JoinPoint joinPoint, Object result) {

        try {
            //result 结果返回的内容
            if (null == result ) {
                return;
            }
//            String signature = joinPoint.getSignature().toString();  // 获取方法签名
//            if (signature.contains("ExampleForLogs.selectYQLists")) {
//
//            }
            //保存日志信息
            if (result instanceof JSONObject) {
                JSONObject jsonObject = (JSONObject) result;
                logService.insertLog(jsonObject.getJSONObject("loginfo"));
            }else{
                JSONObject jsonObject=new JSONObject();
                MethodLog methodLog = this.getMethodRemark(joinPoint);
                jsonObject.put("ywlx",methodLog.openType());
                jsonObject.put("mkbh",methodLog.mkbh());
                jsonObject.put("rzbt",methodLog.remark());
                jsonObject.put("qqurl",methodLog.qqurl());
                jsonObject.put("czipdz",this.getRequestIP(request));
                jsonObject.put("czrbh",UserUtil.getUserInfo("YHBH"));
                logService.insertLog(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 异常通知 用于拦截service层记录异常日志
     *
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(pointcut = "logAspect()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Throwable e) {

    }
    /**
     * 获取方法的中文备注____用于记录用户的操作日志描述
     *
     * @param joinPoint
     * @return
     * @throws Exception
     */
    private MethodLog getMethodRemark(JoinPoint joinPoint) throws Exception {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();

        Class targetClass = Class.forName(targetName);
        Method[] method = targetClass.getMethods();
        for (Method m : method) {
            if (m.getName().equals(methodName)) {
                Class[] tmpCs = m.getParameterTypes();
                if (tmpCs.length == arguments.length) {
                    MethodLog methodCache = m.getAnnotation(MethodLog.class);
                    if (methodCache != null && !("").equals(methodCache.remark())) {
                        return methodCache;
                    }
                    break;
                }
            }
        }
        return null;
    }
    /**
     * 获取参数request
     *
     * @param point
     * @return
     */
    private HttpServletRequest getRequest(JoinPoint point) {
        Object[] args = point.getArgs();
        for (Object obj : args) {
            if (obj instanceof HttpServletRequest)
                return (HttpServletRequest) obj;
        }
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        HttpServletRequest request = sra.getRequest();
        return request;
    }

    /**
     *      * 获取IP
     *      * @param request
     *      * @return
     *     
     */
    private String getRequestIP(HttpServletRequest request) {
        String ip = null;
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        return ip;
    }

    /**
     * 获取前台传过来的参数
     *
     * @param request
     * @return
     */
    private Map getParam(HttpServletRequest request) {
        Map properties = request.getParameterMap();
        Map returnMap = new HashMap();
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            value = null;
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                for (int i = 0; i < values.length; i++) {
                    if (value == null)
                        value = (values[i] == null ? "" : values[i]);
                    else
                        value += "," + (values[i] == null ? "" : values[i]);
                }
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }
}

调用示例:

import com.alibaba.fastjson.JSONObject;
import com.sky.common.entity.base.ResultMap;
import com.sky.rxyWeb.log.MethodLog;
import com.sky.service.zdsj.XtzdsjService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/test")
public class ExampleForLogs {

    @Autowired
    private XtzdsjService xtzdsjService;

    /**
     * 查询所有
     * @return
     */
    @GetMapping("/selectYQList")
    @MethodLog(remark = "XX信息查询",openType = "")
    public JSONObject selectYQLists() {
        JSONObject result = new JSONObject();

        result.put("result", ResultMap.getResultMap(xtzdsjService.selectYQList()));

        //在result中存放日志业务类型、模块编号、日志标题等信息可在切面中获取
        JSONObject loginfo = new JSONObject();
        loginfo.put("rzbh", System.currentTimeMillis());//日志编号
        loginfo.put("ywlx", "1");//业务类型
        loginfo.put("mkbh", "D13");//模块编号
        loginfo.put("rzbt", "XXX查询");//日志标题
        loginfo.put("qqurl", "selectYQList");//请求url
        loginfo.put("czipdz", "XXXXXX");//操作IP地址
        loginfo.put("czrbh", "XXXXXX");//操作人编号
        result.put("loginfo", loginfo);
        return result;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值