美文网首页java
aop系统日志

aop系统日志

作者: 星钻首席小管家 | 来源:发表于2021-01-12 15:33 被阅读0次

    1.自定义注解

    /**
     *自定义注解 拦截Controller 记录日志
     */
    @Target({ElementType.PARAMETER, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public  @interface SystemLog {
    
        String operation() default "";
    
        String type() default "";
    
    }
    

    2.切面逻辑

    @Aspect
    @Component
    public class SystemLogAspect {
    
        @Autowired
        private DailyRecordService dailyRecordService;
    
        /**
         * Controller层切点
         */
        @Pointcut("@annotation(com.yxtech.business.annotation.config.SystemLog)")
        //@Pointcut("execution(* * (..))")
        public void controllerAspect() {
        }
    
        /**
         * 前置通知 用于拦截Controller层记录用户的操作
         *
         * @param joinPoint 切点
         */
        @Before(value = "controllerAspect()")
        public void doBefore(JoinPoint joinPoint) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            try {
                //日志实体对象
                DailyRecord dailyRecord = new DailyRecord();
                if (joinPoint != null) {
                    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                    Method method = signature.getMethod();
                    SystemLog systemLog = method.getAnnotation(SystemLog.class);
                    if (systemLog != null) {
                        // 注解上的描述
                        dailyRecord.setOperation(systemLog.operation());
                        dailyRecord.setType(systemLog.type());
                    }
                    String uuid = UUID.randomUUID().toString();
                    dailyRecord.setId(uuid);
                    dailyRecord.setCreateTime(new Date());
                    dailyRecord.setIp(IpUtils.getIpAddr(request));
                    dailyRecord.setUserName(CurrentAccount.getCurrentAccount().getUserName());
                    //ailyRecord.setUserName("ce shi");
                    dailyRecordService.saveDailyRecord(dailyRecord);
                }
            } catch (Exception e) {
                //记录本地异常日志
                System.out.println("异常方法:"+joinPoint.getTarget().getClass().getName()+",异常代码:" + joinPoint.getSignature().getName()+",异常信息:"+ e.getClass().getName()+","+e.getMessage());
            } finally {
            }
        }
    }
    

    3.在controller的方法上面加注解

    @SystemLog(operation = LogConstant.OPERATION_ACCOUNT,type = LogConstant.TYPE_ADD)
    

    4.如果是spring mvc项目,注意正确配置spring aop,在controller中使用AOP
    ·在controller中使用AOP的问题主要在于如何让controller能够被检测到。
    controller和其他spring bean的区别在于:controller是由mvc定义并在web.xml中的dispatcher中定义的。

    解决方法:
    1、正确定义controller,(比较通用的做法,没有特殊情况的话,大部分应用没有这个问题)
    a. 将服务层的类都放在ApplicationCotext-*.xml中定义,在context listener中初始化(注意,任何controller都不应该在这里出现),要包括<aop:aspectj-autoproxy/>, 在这里,有没有proxy-target-class="true" 没有关系(具体含义参看下文)
    b. 定义mvc的配置文件,一般是 <<servlet name>>-servlet.xml,一般(也是推荐做法)使用auto scan来定义所有的controller.关键步骤来了:这个文件也要加入<aop:aspectj-autoproxy proxy-target-class="true"/>, 一定要添加proxy-target-class="true"! 这是用于通知spring使用cglib而不是jdk的来生成代理方法。
    c. 另外一个事项,controller需要使用@controller注释,而不是继承abstract controller。
    d. 建议使用aspectj来完成aop

    转自:https://www.iteye.com/blog/usherlight-1306111

    相关文章

      网友评论

        本文标题:aop系统日志

        本文链接:https://www.haomeiwen.com/subject/dateaktx.html