spring AOP自定义注解方式实现日志管理

在项目中需要在特定场合进行记录日志,这里使用 spring AOP 自定义注解方式实现日志管理
如果代码中有注解不明白的地方,欢迎提问。

1、spring 配置文件添加

     <!--如果不写proxy-target-class="true"这句话也没问题-->
     <aop:aspectj-autoproxy proxy-target-class="true"/>

2、编写注解类

@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface SysOperationLog {

    /**
     * 操作类型
     */
    String operTypeId() default "";

    /**
     * 方法描述
     */
    String methodDesc();
}

3、编写切面类(这里使用的是环绕通知,切 Controller 和 Service,项目中有些事件不通过Controller 所以 Service 也切过去)

@Component
@Aspect
public class SysOperationLogAspect {
    @Autowired
    private SysOperationLogService sysOperationLogService;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Around("within(@org.springframework.stereotype.Controller * || @org.springframework.stereotype.Service *) && @annotation(sysOperationLog)")
    public Object recordOperationLog(ProceedingJoinPoint jp, SysOperationLog sysOperationLog) throws Throwable {
        logger.debug("[recordOperationLog] start....");
        Map<String, Object> logMap = new HashMap<String, Object>(8);
        Signature sig = jp.getSignature();
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法!");
        }
        logMap.put("method", jp.getSignature().getName());
        logMap.put("methodDesc", sysOperationLog.methodDesc());
        logMap.put("operTypeId", sysOperationLog.operTypeId());
        sysOperationLogService.save(logMap);
        logger.debug("[recordOperationLog] end.");
        return jp.proceed();
    }

4、编写service类(这里使用线程池,异步保存,)

@Service
public class SysOperationLogService {

    @Autowired
    private SysOperationLogDao sysOperationLogDao;
    @Autowired
    @Qualifier("taskExecutor")
    private ThreadPoolTaskExecutor taskExecutor;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 异步保存
     *
     * @param logMap
     */
    public void save(Map<String, Object> logMap) {
        //获取登录人员信息
        logMap.put("operStaffName", ThreadLocalInfoHolder.getLoginUser().getUserName());
        logMap.put("operStaffNbr", ThreadLocalInfoHolder.getLoginUser().getLoginName());
        taskExecutor.execute(new RecordLogHandler(logMap));
    }

    public class RecordLogHandler implements Runnable {
        private Map<String, Object> logMap;

        public RecordLogHandler(Map<String, Object> logMap) {
            this.logMap = logMap;
        }

        @Override
        public void run() {
            logger.debug("#### ThreadName: " + Thread.currentThread().getName() + " record log .");
            sysOperationLogDao.recordLog(logMap);
        }
    }
}

5、编写dao类

@Repository
public class SysOperationLogDao extends BaseJdbcDao {

    public int recordLog(Map<String, Object> params) {
        Iterator<String> it = params.keySet().iterator();
        for (; it.hasNext(); ) {
            String k = it.next();
            logger.debug(k + "=" + MapUtils.getString(params, k));
        }
        StringBuilder sb = new StringBuilder(256);
        sb.append("INSERT INTO AST_CHECK_OPERATION_LOG \n");
        sb.append("  (LOG_ID, OPER_TYPE_ID, OPER_STAFF_NBR, OPER_STAFF_NAME, OPER_DATE, \n");
        sb.append("   TASK_ID, TASK_NAME, TASK_CODE, AST_ID, AST_CODE) \n");
        sb.append("VALUES \n");
        sb.append("  (SEQ_AST_CHECK_OPERATION_LOG.NEXTVAL, ?, ?, ?, SYSDATE) \n");
        return getJdbcTemplate().update(sb.toString(),
                MapUtils.getString(params, "operTypeId", ""),
                MapUtils.getString(params, "operStaffNbr", ""),
                MapUtils.getString(params, "operStaffName", "")
    }
}

6、测试类方法

@SysOperationLog(methodDesc = "查询操作", operTypeId = "803")
    public Map<String, Object> queryInventoryHistoryList(Map<String, Object> param) {     
        System.out.println("记录查询"); 
    }

如果在实际的项目中运行效率不好,在这里请看到博客的大牛给点建议!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值