SpringAOP xml 方式和注解简单实现日志处理

1.首先是用注解方式捕捉Controller 层异常:

首先是引入aop 依赖的jar

<!-- Spring AOP 日志管理需要导入的包 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.13</version>
        </dependency>
 
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>

其次是在applicationg.xml spring 容器中加入 aop 配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" ....

xsi:schemaLocation="
 ...
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd


 在application 添加spring配置代理

 <!-- proxy-target-class="true"配置使Spring采用CGLIB代理  proxy-target-class="false" 配置使Spring采用JDK代理--><!-- 开启@aspectJ切面注解器   默认是flase -->
   <aop:aspectj-autoproxy  />

添加自定义注解: 

package com.buDun.test.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Retention(RetentionPolicy.RUNTIME)
//@Target({ElementType.METHOD,ElementType.FIELD})
@Target(ElementType.METHOD)
@Documented
public @interface Loggable {
  /**Insert,Update,Delete,Select */
  String optType() default "";
  /** 描述*/
  String describe() default "";
  /**模块 */
  String module() default "";
}

参考:http://mini.eastday.com/bdmip/180411141722960.html

定义一个切面:

注意:@AfterReturning 注解args参数中一定有,returning="retVal" 并且注解参数名称 和方法参数名称相同

     @AfterThrowing  注解也是:注解args参数一定有throwing="ex"  并且注解参数名称和方法参数名称相同

    捕捉异常处理:可以使用@around   获取  ptpJoinPoint.proceed(); 捕捉异常处理在返回给前端;

package com.BaDun.test.aop;

import java.lang.reflect.Method;
import java.util.Objects;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.BaDun.test.annotation.Loggable;
import com.BaDun.test.common.AppResult;

/**
 * Aop接收打印日志.
 * <p>主要用来截取controller的日志处理和异常捕获</p>
 * @author jhon07
 * @version 1.11
 * 
 */
@Aspect
@Component("loggerAspect")
public class LoggerAspect {
	
	private Logger logger=LoggerFactory.getLogger(LoggerAspect.class);
	
	@Pointcut("@annotation(com.BaDun.test.annotation.Loggable)")
	public void log(){};
	/**
	 * 
	 * @param joinPoint
	 * @param retVal
	 * @return  JSONObject
	 * @author qienay
	 * @since 1.11
	 * 
	 */
	@AfterReturning(value="log()",returning="retVal")
	public JSONObject log(JoinPoint joinPoint,JSONObject retVal){
		//获取参数值
		Object[] args = joinPoint.getArgs();
		//获取方法名称
		String methodName=joinPoint.getSignature().getName();
		//获取相应的类
	    Class<?> targetClass=joinPoint.getTarget().getClass();
	    Method method=null;
	    for(Method mt:targetClass.getMethods()){
	    	if(methodName.equals(mt.getName())){
	    		method=mt;
	    		break;
	    	}
	    }
	    Loggable loggable = method.getAnnotation(Loggable.class);
	    if(Objects.isNull(loggable)){
	    	return retVal ;
	    }
	    logger.info("loggable desc:{} ,opType:{},module:{}",loggable.describe(),loggable.optType(),loggable.module(),args);
	    return retVal;
	};
	/**
	 * 方法处理后异常打印.
	 * @deprecated
	 * @param joinPoint
	 * @param ex
	 * @return void
	 */
	@AfterThrowing(value="log()",throwing="ex")
	public void log(JoinPoint joinPoint,Exception ex){
		//获取参数值
		Object[] args = joinPoint.getArgs();
		//获取方法名称
		String methodName = joinPoint.getSignature().getName();
		//获取相应类
		Class<?> targetClass = joinPoint.getTarget().getClass();
	    Method method=null;
	    for(Method mt:targetClass.getMethods()){
	    	if(methodName.equals(mt.getName())){
	    		method=mt;
	    		break;
	    	}
	    }
	    Loggable loggable = method.getAnnotation(Loggable.class);
	    if(Objects.isNull(loggable)){
	    	return ;
	    }
	    logger.info("loggable desc:{},opType:{},module:[],exception:{},params{}",loggable.describe(),loggable.optType(),loggable.module(),ex.getMessage(),args);
	    
	}
	 /**
	  * 环绕通知主要用来处理Controller层 异常.
	  * <p>controller 层类{@link com.BaDun.test.controller.testController}<p>
	  * @param joinPoint
	  * @return JSONObject
	  * @author jhon07
	  * @since 1.11
	  */
	 @Around(value="log()") 
	  public JSONObject authorSessionAfter(ProceedingJoinPoint ptpJoinPoint){
		  JSONObject messageJson=null;
		  String methodName=null;
		  Loggable loggable=null;
		  try {
			
			//Object proceed = joinPoint.proceed();
			//获取方法名
			  methodName= ptpJoinPoint.getSignature().getName();
			 
			//获取类型名称
			Class<?> targetClass = ptpJoinPoint.getTarget().getClass();
			Method method=null;
			
			  for(Method mt:targetClass.getMethods()){
			    	if(methodName.equals(mt.getName())){
			    		method=mt;
			    		break;
			    	}
			    }
		   loggable = method.getAnnotation(Loggable.class);
		    //获取controller传递的值
			Object proceed = ptpJoinPoint.proceed();
			messageJson=JSON.parseObject(proceed.toString());
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			String  message=methodName+" "+loggable.module()+"异常!";
			logger.info(message);
			messageJson=AppResult.getFaileMsg(message);
			e.printStackTrace();
		}
		  
		return messageJson;
	  }

}

注意:controller 层  方法为public 不管是CGlib 还是JDK 创建代理类,首先得能访问这个类.方法;

@Loggable(describe="查询Jhon07信息", module = "查询", optType = "POST")
	@RequestMapping(value = { "/queryUserInfo" }, method = { RequestMethod.POST }, produces={"application/json;charset=UTF-8"})
	@ResponseBody
	public void queryUserInfo(....){}

2.使用注解方式实现:

首先是在appliction.xml spring 容器中加入:aop配置

需要注意的是:mehod 不能像注解一样,使用重载方式,这里的method 的名字都不同的

   <!-- AOP配置 -->
   <aop:config>
    <aop:aspect id="controllerAspect" ref="loggerAspects">
      <aop:pointcut expression="execution(* com.buDun.test.controller.*.*(..))" id="controllPoincut" />
      <aop:around pointcut-ref="controllPoincut" method="aroundLog" />
      <aop:after-returning pointcut-ref="controllPoincut" method="afterReturningLog" returning="retVal" />
    <!--   <aop:after-throwing pointcut-ref="controllPoincut" method="AfterThrowingLog" throwing="ex"/> -->
    </aop:aspect>
   </aop:config>

定义切面类:

package com.buDun.test.aop;

import java.lang.reflect.Method;
import java.util.Objects;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.buDun.test.annotation.Loggable;
import com.buDun.test.common.AppResult;

/**
 * Aop接收打印日志.
 * <p>主要用来截取controller的日志处理和异常捕获</p>
 * @author jhon07
 * @version 1.11
 * 
 */
@Component("loggerAspects")
public class LoggerAspects {
	
	private Logger logger=LoggerFactory.getLogger(LoggerAspect.class);
	
	public void log(){};
	/**
	 * 
	 * @param joinPoint
	 * @param retVal
	 * @return  JSONObject
	 * @author qienay
	 * @since 1.11
	 * 
	 */
	public JSONObject afterReturningLog(JoinPoint joinPoint,JSONObject retVal){
		//获取参数值
		Object[] args = joinPoint.getArgs();
		//获取方法名称
		String methodName=joinPoint.getSignature().getName();
		//获取相应的类
	    Class<?> targetClass=joinPoint.getTarget().getClass();
	    Method method=null;
	    for(Method mt:targetClass.getMethods()){
	    	if(methodName.equals(mt.getName())){
	    		method=mt;
	    		break;
	    	}
	    }
	    Loggable loggable = method.getAnnotation(Loggable.class);
	    if(Objects.isNull(loggable)){
	    	return retVal ;
	    }
	    logger.info("loggable desc:{} ,opType:{},module:{}",loggable.describe(),loggable.optType(),loggable.module(),args);
	    return retVal;
	};
	/**
	 * 方法处理后异常打印.
	 * @deprecated
	 * @param joinPoint
	 * @param ex
	 * @return void
	 */
	public void AfterThrowingLog(JoinPoint joinPoint,Exception ex){
		//获取参数值
		Object[] args = joinPoint.getArgs();
		//获取方法名称
		String methodName = joinPoint.getSignature().getName();
		//获取相应类
		Class<?> targetClass = joinPoint.getTarget().getClass();
	    Method method=null;
	    for(Method mt:targetClass.getMethods()){
	    	if(methodName.equals(mt.getName())){
	    		method=mt;
	    		break;
	    	}
	    }
	    Loggable loggable = method.getAnnotation(Loggable.class);
	    if(Objects.isNull(loggable)){
	    	return ;
	    }
	    logger.info("loggable desc:{},opType:{},module:[],exception:{},params{}",loggable.describe(),loggable.optType(),loggable.module(),ex.getMessage(),args);
	    
	}
	 /**
	  * 环绕通知主要用来处理Controller层 异常.
	  * <p>controller 层类{@link com.buDun.test.controller.testController}<p>
	  * @param joinPoint
	  * @return JSONObject
	  * @author jhon07
	  * @since 1.11
	  */
	  public JSONObject aroundLog(ProceedingJoinPoint ptpJoinPoint){
		  JSONObject messageJson=null;
		  String methodName=null;
		  Loggable loggable=null;
		  try {
			
			//Object proceed = joinPoint.proceed();
			//获取方法名
			  methodName= ptpJoinPoint.getSignature().getName();
			 
			//获取类型名称
			Class<?> targetClass = ptpJoinPoint.getTarget().getClass();
			Method method=null;
			
			  for(Method mt:targetClass.getMethods()){
			    	if(methodName.equals(mt.getName())){
			    		method=mt;
			    		break;
			    	}
			    }
		   loggable = method.getAnnotation(Loggable.class);
		    //获取controller传递的值
			Object proceed = ptpJoinPoint.proceed();
			messageJson=JSON.parseObject(proceed.toString());
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			String  message=methodName+" "+loggable.module()+"异常!";
			logger.info(message);
			messageJson=AppResult.getFaileMsg(message);
			e.printStackTrace();
		}
		  
		return messageJson;
	  }

}

参考:https://blog.csdn.net/kawnj/article/details/84639159

           https://docs.spring.io/spring-framework/docs/5.1.3.RELEASE/spring-framework-reference/core.html#aop-introduction-proxies

猜你喜欢

转载自blog.csdn.net/JHON07/article/details/86425947