1. 程式人生 > >aop日誌(記錄方法調用日誌)

aop日誌(記錄方法調用日誌)

dex bsp ram org rip his == name 標註

一,使用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("\t==>參數[" + i + "]:\t" + 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("\t==>參數["+i+"]:\t"+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:\t"+joinPoint.getKind());
                System.out.println("Target:\t"+joinPoint.getTarget().toString());
                Object[] os=joinPoint.getArgs();
                System.out.println("Args:");
                for(int i=0;i<os.length;i++){
                    System.out.println("\t==>參數["+i+"]:\t"+os[i].toString());
                }
                System.out.println("Signature:\t"+joinPoint.getSignature());
                System.out.println("SourceLocation:\t"+joinPoint.getSourceLocation());
                System.out.println("StaticPart:\t"+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();
                }
            }

aop日誌(記錄方法調用日誌)