1、Aop 切面 Feign 记录
/**
* @author xpy
* @desc
* @date 2019/9/6 10:17
*/
@Component
@Scope("prototype")
@Aspect
public class FeignLogAop {
private Logger logger= LoggerFactory.getLogger(getClass());
@Resource
private InterfaceDataRecordMapper interfaceDataRecordMapper;
private InterfaceDataRecordWithBLOBs recordWithBLOBs;
/**
* 功能描述: 定义切点切人feign.client包下所有类
* @Return: void
* @Author: XPY
* @Date: 2019/9/6 11:25
*/
@Pointcut("execution(* com.yiyu.feign.client..*.*(..)) ")
public void executeService(){}
/**
* 功能描述: 方法执行前切入
* @Param: [joinPoint]
* @Return: void
* @Author: XPY
* @Date: 2019/9/6 11:26
*/
@Before(value = "executeService()")
public void beforeAdvice(JoinPoint joinPoint){
try {
if(this.recordWithBLOBs == null){
this.recordWithBLOBs = new InterfaceDataRecordWithBLOBs();
}
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
PostMapping postMapping = method.getAnnotation(PostMapping.class);
GetMapping getMapping = method.getAnnotation(GetMapping.class);
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
if(postMapping == null && getMapping == null && requestMapping == null){
return;
}
String[] value = new String[]{};
if(postMapping != null){
value = postMapping.value();
}
if(getMapping != null){
value = getMapping.value();
}
if(requestMapping != null){
value = requestMapping.value();
}
if(value.length <= 0){
return;
}
Object[] args = joinPoint.getArgs();
this.recordWithBLOBs.setInterfaceUrl(value[0]);
this.recordWithBLOBs.setInterfaceDataRecordId(GenerateCode.randomUUID());
this.recordWithBLOBs.setInterfaceParam(JSONObject.toJSONString(args));
}catch (Exception e){
e.printStackTrace();
logger.error(e.getMessage());
}
}
/**
* 功能描述: 方法执行返回值时
* @Param: [obj]
* @Return: void
* @Author: XPY
* @Date: 2019/9/6 11:26
*/
@AfterReturning(value = "executeService()" , returning="obj")
public void afterAdviceReturn(Object obj){
try {
if(obj != null){
JSONObject jsonObject = JSON.parseObject((String)obj);
Integer status = jsonObject.getInteger("Code")!=null?jsonObject.getInteger("Code"):jsonObject.getInteger("status");
this.recordWithBLOBs.setInterfaceFlag(status);
this.recordWithBLOBs.setInterfaceResult(JSONObject.toJSONString(obj));
interfaceDataRecordMapper.insert(this.recordWithBLOBs);
}
}catch (Exception e){
e.printStackTrace();
logger.error(e.getMessage());
}
}
}
Pointcut
匹配包
-
匹配ProductService类里头的所有方法 @Pointcut("within(com.zhb.service.ProductService)")
-
匹配com.zhb包及子包下所有类的方法 @Pointcut("within(com.zhb..*)")
匹配对象
-
匹配AOP对象的目标对象为指定类型的方法,即LogService的aop代理对象的方法 @Pointcut("this(com.zhb.log.Loggable)")
-
匹配实现Loggable接口的目标对象(而不是aop代理后的对象)的方法 @Pointcut("target(com.zhb.log.Loggable)")
匹配所有以Service结尾的bean里头的方法 @Pointcut("bean(*Service)")
匹配参数 args()
-
匹配任何以find开头而且只有一个Long参数的方法 @Pointcut("execution(* ..find(Long))")
-
匹配任何以find开头的而且第一个参数为Long型的方法 @Pointcut("execution(* ..find(Long,..))")
-
匹配任何只有一个Long参数的方法 @Pointcut("within(com.zhb..*) && args(Long)")
-
匹配第一个参数为Long型的方法 @Pointcut("within(com.zhb..*) && args(Long,..)")
匹配注解
-
匹配方法标注有AdminOnly的注解的方法 @Pointcut("@annotation(com.zhb.anno.AdminOnly) && within(com.zhb..*)")
-
匹配标注有NeedSecured的类底下的方法 //class级别 @Pointcut("@within(com.zhb.anno.NeedSecured) && within(com.zhb..*)")
-
匹配标注有NeedSecured的类及其子类的方法 //runtime级别
-
在spring context的环境下,二者没有区别 @Pointcut("@target(com.zhb.anno.NeedSecured) && within(com.zhb..*)")
-
匹配传入的参数类标注有Repository注解的方法 @Pointcut("@args(com.zhb.anno.NeedSecured) && within(com.zhb..*)")
匹配方法
-
匹配任何公共方法 @Pointcut("execution(public * com.zhb.service..(..))")
-
匹配com.zhb包及子包下Service类中无参方法 @Pointcut("execution(* com.zhb..Service.())")
-
匹配com.zhb包及子包下Service类中的任何只有一个参数的方法 @Pointcut("execution(* com.zhb..Service.(*))")
-
匹配com.zhb包及子包下任何类的任何方法 @Pointcut("execution(* com.zhb...(..))")
-
匹配com.zhb包及子包下返回值为String的任何方法 @Pointcut("execution(String com.zhb...(..))")
-
匹配异常 execution(public * com.zhb.service..(..) throws java.lang.IllegalAccessException)
通知类型
-
Before:在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可
-
AfterReturning:在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值
-
AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名来访问目标方法中所抛出的异常对象
-
After:在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式
-
Around:环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint