zoukankan      html  css  js  c++  java
  • aop日志(记录方法调用日志)

    一,使用aop记录方法调用日志

      1)使用注解与aop做方法调用日志,只需要把注解添加在要记录的方法上就可以,不会影响代码结构

      2)实现思路 数据库表建立>>配置需要环境>>自定义注解>>定义切点与操作(包含处理逻辑)>>添加注解

    二,配置环境

      1)在原来的项目pom文件中添加以下aop需要的依赖

         <springframework>4.0.5.RELEASE</springframework>
            <aspectj>1.8.5</aspectj>
    
          
            <!-- Spring AOP -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${springframework}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectj}</version>
            </dependency>    

      2)springmvc配置

      
     xmlns:aop="http://www.springframework.org/schema/aop"

      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-4.0.xsd



    <!--
    启动AspectJ支持 只对扫描过的bean有效 --> <aop:aspectj-autoproxy proxy-target-class="true" /> <!-- 指定Sping组件扫描的基本包路径 --> <context:component-scan base-package="com.bjsxt.portl"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>

    三,自定义注解

      1)  

    import java.lang.annotation.ElementType;
            import java.lang.annotation.Retention;
            import java.lang.annotation.RetentionPolicy;
            import java.lang.annotation.Target;
            /**
             * 日志记录
             * @author heyuan***
             * @date: 2017年11月22日 上午11:41:57
             */
            @Retention(RetentionPolicy.RUNTIME)
            @Target({ElementType.METHOD})
            public @interface Log {
                String name() default ""; //用于写方法作用
            }

    四,定义切点与操作

      1)

    @Aspect
    @Component
    public class SeriveLogAop
    {
    
      @Resource
      private OperationLogMapper operationLogMapper;
    
      @Pointcut("@annotation(com.bjsxt.portal.annotation.SeriveLog)")
      public void SeriveLogAopqd()
      {
        System.out.println("---------->切点");
      }
    
      @After("SeriveLogAopqd()")
      public void Afters(JoinPoint joinPoint)
      {
        OperationLog operationLog = new OperationLog();
        User user = new User();
        StringBuffer arg = new StringBuffer();
    
        Object[] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; ++i) {
          System.out.println("	==>参数[" + i + "]:	" + args[i].toString());
          arg.append(args[i].toString());
        }
    
        Signature signature = joinPoint.getSignature();
        String signa = signature.toString();
    
        MethodSignature ms = (MethodSignature)joinPoint.getSignature();
        Method method = ms.getMethod();
    
        String name = ((SeriveLog)method.getAnnotation(SeriveLog.class)).name();
    
        String name2 = method.getName();
    
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    
        user.setuUsername("无登录人");
    
        String host = request.getRemoteHost();
    
        String username = user.getuUsername();
    
        String time = Time.getTime();
    
        operationLog.setoIp(host);
        operationLog.setuUsername(username);
        operationLog.setoTime(time);
        operationLog.setoMethodname(name2);
        operationLog.setoExplain(name);
        operationLog.setoFullpath(signa);
        operationLog.setoParameter(arg.toString());
    
        this.operationLogMapper.addOperationLogs(operationLog);
      }
    }

    五,在需要记录的方法上添加@Log(name="方法描述")

    六,常用知识

      

    注解:
    
            @Before – 目标方法执行前执行  前置通知 JoinPoint joinPoint
    
            @After – 目标方法执行后执行      后置通知
    
            @AfterReturning – 目标方法返回后执行,如果发生异常不执行
    
            @AfterThrowing – 异常时执行      异常通知 
    
            @Around – 在执行上面其他操作的同时也执行这个方法  环绕通知 ProceedingJoinPoint pjp   执行方法:pjp.proceed(); 要返回pjp  
    joinPoint:方法
        joinPoint.getKind() // method-execution 
        joinPoint.getTarget().toString()// 获取连接点所在的目标对象; com.xxx.portal.service.impl.UserServiceImpl@a269a21
        joinPoint.getArgs() //获取连接点方法运行时的入参列表;
            System.out.println("Args:");
            for(int i=0;i<os.length;i++){
                System.out.println("	==>参数["+i+"]:	"+os[i].toString());
            }
        joinPoint.getSignature() //获取连接点的方法签名对象;String com.bjsxt.portal.service.impl.UserServiceImpl.getUser(User,HttpServletRequest,HttpSession)
        joinPoint.getSourceLocation() // org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@161b0ee2
        joinPoint.getStaticPart() //    execution(String com.xxx.portal.service.impl.UserServiceImpl.getUser(User,HttpServletRequest,HttpSession))    
        
        MethodSignature ms=(MethodSignature) joinPoint.getSignature();
            Method method=ms.getMethod();
            method.getAnnotation(Log.class).name();
            //method.getAnnotation(Log.class).name()  获取操作名(@log(name="内容"))
            method.getName(); //获取当前执行方法名
    常用方法:
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
         request.getSession();
         request.getHost();//获取ip
         
         异常名称: e.getClass().toString()
    网络参考资料
    @Aspect
            @Component
            public class LogAop {
                
                ThreadLocal<Long> time=new ThreadLocal<Long>();
                ThreadLocal<String> tag=new ThreadLocal<String>();
                
                //切点
                @Pointcut("@annotation(com.bjsxt.portal.annotation.Log)")
                public void logqd() {
                    System.out.println("---------->切点");
                }
                
                /**
                 * 在所有标注@Log的地方切入
                 * @param joinPoint
                 * 前置通知
                 */
                @Before("logqd()")
                public void beforeExec(JoinPoint joinPoint){
                    
                    time.set(System.currentTimeMillis());
                    tag.set(UUID.randomUUID().toString());
                    
                    info(joinPoint);
                    
                    MethodSignature ms=(MethodSignature) joinPoint.getSignature();
                    Method method=ms.getMethod();
                    //method.getAnnotation(Log.class).name()  获取操作名(@log(name="内容"))
                    System.out.println(method.getAnnotation(Log.class).name()+"标记"+tag.get());
                }
                /**
                *后置通知
                */
                @After("logqd()")
                public void afterExec(JoinPoint joinPoint){
                    MethodSignature ms=(MethodSignature) joinPoint.getSignature();
                    Method method=ms.getMethod();
                    System.out.println("标记为"+tag.get()+"的方法"+method.getName()+"运行消耗"+(System.currentTimeMillis()-time.get())+"ms");
                }
                
                /**
                *环绕通知
                */
                @Around("logqd()")
                public Object aroundExec(ProceedingJoinPoint pjp) throws Throwable{
                    System.out.println("前");
                    Object proceed = pjp.proceed();
                    System.out.println("后");
                    return proceed;
                }
                
                private void info(JoinPoint joinPoint){
                    System.out.println("--------------------------------------------------");
                    System.out.println("King:	"+joinPoint.getKind());
                    System.out.println("Target:	"+joinPoint.getTarget().toString());
                    Object[] os=joinPoint.getArgs();
                    System.out.println("Args:");
                    for(int i=0;i<os.length;i++){
                        System.out.println("	==>参数["+i+"]:	"+os[i].toString());
                    }
                    System.out.println("Signature:	"+joinPoint.getSignature());
                    System.out.println("SourceLocation:	"+joinPoint.getSourceLocation());
                    System.out.println("StaticPart:	"+joinPoint.getStaticPart());
                    System.out.println("--------------------------------------------------");
                }
                
                
            }
            
            
                    /**
                 * 异常通知
                 *@descript
                 *@param point
                 *@version 1.0
                 */
                @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")  
                public  void doAfterThrowing(JoinPoint point, Throwable e) {  
                    LogFormMap logForm = new LogFormMap();
                     Map<String, Object> map = null;
                    String user = null;
                    String ip = null;
                    try {
                        ip = SecurityUtils.getSubject().getSession().getHost();
                    } catch (Exception ee) {
                        ip = "无法获取登录用户Ip";
                    }
                    try {
                        map=getControllerMethodDescription(point);
                        // 登录名
                        user = SecurityUtils.getSubject().getPrincipal().toString();
                        if (Common.isEmpty(user)) {
                            user = "无法获取登录用户信息!";
                        }
                    } catch (Exception ee) {
                        user = "无法获取登录用户信息!";
                    }
                    
                    logForm.put("accountName",user);
                    logForm.put("module",map.get("module"));
                    logForm.put("methods","<font color="red">执行方法异常:-->"+map.get("methods")+"</font>");
                    logForm.put("description","<font color="red">执行方法异常:-->"+e+"</font>");
                    logForm.put("actionTime","0");
                    logForm.put("userIP",ip);
                    try {
                        logMapper.addEntity(logForm);
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
  • 相关阅读:
    SQL语法分类
    SQL语法入门
    数据库的基本对象
    数据库基础
    数据库概述
    设计模式之备忘录模式
    设计模式之State模式
    设计模式之装饰模式
    简单工厂模式
    初识C#设计模式
  • 原文地址:https://www.cnblogs.com/hi-feng/p/7895925.html
Copyright © 2011-2022 走看看