zoukankan      html  css  js  c++  java
  • 通过AOP自定义注解实现记录用户操作日志。

    前言:

    通过自定义注解和AOP结合的方式,实现日志的记录功能

    大致流程:项目运行->用户操作调用业务处理类->通过自定义的注解(我理解为一个切点)->进入到AOP切面类(在这里可以获得业务处理类的类名,方法名,通过request获取操作者ip,自定义的操作名,时间等)->把获取的信息记入数据库实现日志的记录->记录成功后返回业务处理类,下面是代码。

    1.spring-mvc配置文件

        <!-- 6.开启注解AOP (前提是引入aop命名空间和相关jar包) -->
        <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"></aop:aspectj-autoproxy>
    
        <!-- 7.开启aop,对类代理强制使用cglib代理 -->
        <aop:config proxy-target-class="true"></aop:config>
    
        <!-- 8.扫描 @Service @Component 注解-->
        <context:component-scan base-package="com.bs" >
            <!-- 不扫描 @Controller的类 -->
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    

      

    2.自定义注解类

    package com.bs.annotation;
    
    import java.lang.annotation.*;
    
    
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface SysLog {
    
    	String value() default "";
    }
    

      

    3.AOP切面类

    package com.bs.aop;
    
    import java.lang.reflect.Method;
    import java.text.DateFormat;
    import java.util.Date;
    import java.util.Enumeration;
    import javax.servlet.http.HttpServletRequest;
    import org.apache.commons.lang.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import com.bs.annotation.SysLog;
    import com.bs.basic.service.BsSysLogService;
    
    @Aspect
    @Component
    public class LogAspect {
    
    	
        private static final String LOG_CONTENT = "[类名]:%s <br/>[方法]:%s <br>[参数]:%s <br/>[IP]:%s";
        
        @Autowired
        public BsSysLogService logService;
        
        @Around("@annotation(com.bs.annotation.SysLog)")
        public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable{
    		
    		DateFormat ddtf = DateFormat.getDateTimeInstance();
    		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    		HttpServletRequest request = attributes.getRequest();
    		Object result = null;
    		String methodName = joinPoint.getSignature().getName();
            Method method = currentMethod(joinPoint, methodName);
            SysLog log = method.getAnnotation(SysLog.class);
            String content =buildeContent(joinPoint, methodName, request);
            
            logService.insert(content,ddtf.format(new Date()),"-",log.value());
            try{
            	result=joinPoint.proceed();
            }catch(Exception exception){
            	
            }finally{
            }
            return result;
    	}
    	
    	 /**
         * 获取当前方法
         * @param joinPoint
         * @param methodName
         * @return
         */
        public  Method currentMethod(ProceedingJoinPoint joinPoint,String methodName){
            Method[] methods = joinPoint.getTarget().getClass().getMethods();
            Method resultMethod = null;
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    resultMethod = method;
                    break;
                }
            }
            return resultMethod;
        }
        
        /**
         * 日志内容
         * @param joinPoint
         * @param methodName
         * @param request
         * @return
         */
        public String buildeContent(ProceedingJoinPoint joinPoint, String methodName, HttpServletRequest request) {
            String className = joinPoint.getTarget().getClass().getName();
            Object[] params = joinPoint.getArgs();
            StringBuffer bf = new StringBuffer();
            if (params != null && params.length > 0) {
                Enumeration<String> paraNames = request.getParameterNames();
                while (paraNames.hasMoreElements()) {
                    String key = paraNames.nextElement();
                    bf.append(key).append("=");
                    bf.append(request.getParameter(key)).append("&");
                }
                if (StringUtils.isBlank(bf.toString())) {
                    bf.append(request.getQueryString());
                }
            }
            return String.format(LOG_CONTENT, className, methodName, bf.toString(),getRemoteAddress(request));
        }
        
        
        /**
        *
        * 获取请求客户端ip
        *
        * @param request
        *
        * @return ip地址
        *
        */
       public static  String getRemoteAddress(HttpServletRequest request) {
    
           String ip = request.getHeader("x-forwarded-for");
           if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
               ip = request.getHeader("Proxy-Client-IP");
           }
           if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
               ip = request.getHeader("WL-Proxy-Client-IP");
           }
           if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {
               ip = request.getRemoteAddr();
           }
           return ip;
       }
    }

    4.自定义注解配置在需要记录的业务处理类

    @SysLog("删除场景")
    	@Override
    	public String deleteScene(String cmdValues) {
    		//业务逻辑....
    	}
    
    @SysLog("更新场景")
    	@Override
    	public String updateScene(String value) {
            //业务处理...
    }
    

    ...

    记录的日志是这样的

  • 相关阅读:
    Linux下SVN(Subversion)自动启动脚本
    Linux安装SVN
    【转】utf-8的中文是一个汉字占三个字节长度
    24-《分布式系统架构的本质》系列04——分布式系统关键技术:全栈监控
    23-《分布式系统架构的本质》系列03——分布式系统的技术栈
    22-《分布式系统架构的本质》系列02——从亚马逊的实践,谈分布式系统的难点
    由 leetcode 136. Single Number 引出的异或总结
    【工具软件】-Beyond Compare4 试用到期
    01-更新软件源
    01-程序员也要会项目管理
  • 原文地址:https://www.cnblogs.com/zh-peng/p/10622878.html
Copyright © 2011-2022 走看看