Spring AOP 记录日志

Spring AOP 最常用的地方之一就是记录日志,这里记录除了记录日志描述外,还记录了方法请求的参数,并将记录保存到数据库。这里用到了自定义注解,使用如下

1. 创建 log 日志类,并生产相应的pojo,pojo如下

public class OperationLog implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 7087799444017468909L;
    private Integer id;
    private String userId;
    private String operatType;
    private String content;
    private String remarks;
    private Date create;

    // getXXX()和setXXX()省略
}

2. 创建注解类 SystemServiceLog

/**
 * AOP 日志记录,自定义注解
 * @author xxx
 * @since JDK1.8
 */
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemServiceLog {

    // 日志描述
    String description() default "";

    // 操作类型
    int tableType() default 0;
}

省略创建dao和service的代码

3. 创建拦截方法,这里只在请求前拦截

@Aspect
@Component
public class SystemLogAspect {

    @Autowired 
    private OperationLogService operationLogService;

    @Pointcut("@annotation(com.xxx.common.annotation.SystemServiceLog)")
    public void serviceAspect() {

    }


    @After("serviceAspect()")
    public void doServiceLog(JoinPoint joinPoint) {
        // 获取用户信息
        Session session = SecurityUtils.getSubject().getSession();
        UserInfo user = (UserInfo) session.getAttribute(ShiroDbRealm.SESSIOIN_USER_KEY);

        OperationLog log = new OperationLog();

        try {
            String content = getServiceMthodDescription(joinPoint);
            log.setContent(user.getRealName() + content);
            log.setRemarks(getServiceMethodParams(joinPoint));
            log.setUserId(user.getId());
            String operatType = getServiceMthodTableType(joinPoint);
            log.setOperatType(operatType);
            operationLogService.insert(log);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取注解中对方法的描述信息 用于service层注解
     * @param joinPoint 切点
     * @return 方法描述
     * @throws ClassNotFoundException
     */
    private String getServiceMthodDescription(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String description = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemServiceLog.class).description();
                    break;
                }
            }
        }

        return description;
    }

    /**
     * 获取注解方法中的描述信息  用于 Service 层注解
     * @param joinPoint 切点
     * @return 方法描述
     * @throws ClassNotFoundException
     */
    private String getServiceMthodTableType(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Object[] arguments = joinPoint.getArgs();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String description = "";
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs.length == arguments.length) {
                    description = method.getAnnotation(SystemServiceLog.class).description();
                    break;
                }
            }
        }

        return description;
    }

    /**
     * 获取json格式的参数<br>
     * 
     * @param joinPoint
     * @return
     * @since JDK1.8
     */
    private String getServiceMethodParams(JoinPoint joinPoint) {
        Object[] arguments = joinPoint.getArgs();
        if (arguments == null || arguments.length == 0) {
            return "无参数";
        }
        List<Object> list = new ArrayList<>(Arrays.asList(arguments));
        String params = JsonUtil.getJsonStringFromPOJO(list);
        return params;
    }
}

4. 在service的实现类的方法上使用自定义注解记录日志

@Override
    @Transactional
    @SystemServiceLog(description=Constants.CLIENT_SELECT_LIST, tableType=Constants.USER_TABLE_TYPE)
    public Map<String, Object> queryXXX(String name, String address) {
        Map<String, Object> map = new HashMap<>();
        // 省略
        return map;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值