几个稍微复杂的切入点表达式
1、某个包下的所有类,且排除掉其中的一个类
tips: tech.cxcool.test.controller包下除了AttachController之外的所有Controller都会被该切面拦截到
@Pointcut(value = "execution(public * tech.cxcool.test.controller.*.*(..))&&!execution(public * tech.cxcool.test.controller.AttachController.*(..))")
2、既要包含类上的注解,也要包含类内方法上的注解
tips: @AddBusiId在类上使用或者在方法上使用都会被切面拦截到@annotation(tech.cxcool.test.common.annotation.AddBusiId)||@within(tech.cxcool.test.common.annotation.AddBusiId)
AOP+自定义注解
实战1
tips: 使用spring中的AOP,完成向返回值中添加busiId的功能,注意,这个busiId是个定值,是从注解@AddBusiId里面的属性值中获取到的。
highlights:
- 使用spring中的工具类AnnotationUtils对注解进行处理,用于获取标注在“方法”或者“类”上的注解,并获取相应的注解的属性值。
- 如果存在方法级别的注解,会优先于类级别的注解进行处理。
注解
public @interface AddBusiId {
String value() default "";
}
切面
/**
* author: panhe
* create_time: 2021/7/6 19:10
* description:
* 切面类 :向接口返回对象中追加busiId字段,值为注解中带入的value值
*
*/
@Component
@Aspect
public class ResAddBusiIdAop {
@Pointcut("@annotation(tech.cxcool.test.common.annotation.AddBusiId)||@within(tech.cxcool.test.common.annotation.AddBusiId)")
public void point1() {}
@Around("point1()")
public Object test(ProceedingJoinPoint pjp) throws Throwable {
// System.out.println("进入切面....");
Object obj = pjp.proceed();
if(obj instanceof ResponseEntity){
ResponseEntity res = (ResponseEntity)obj ;
ResObject res2= (ResObject)res.getBody();
String busiId = getBusiId(pjp);
ResObjectExt resObjectExt = new ResObjectExt(res2,busiId);
return new ResponseEntity(resObjectExt, HttpStatus.OK);
}
return obj ;
}
//-----------------------私有方法----------------------
/**
* 获取指定注解的属性值
* @param pjp
* @return
*/
private String getBusiId(ProceedingJoinPoint pjp) throws NoSuchMethodException {
// System.out.println("获取方法上的注解--------------->");
Class<?> targetCls=pjp.getTarget().getClass();
MethodSignature ms=(MethodSignature)pjp.getSignature();
Method targetMethod=
targetCls.getDeclaredMethod(
ms.getName(),
ms.getParameterTypes());
Annotation methodAnno = AnnotationUtils.findAnnotation(targetMethod,AddBusiId.class);
if(methodAnno !=null){
Object val = AnnotationUtils.getValue(methodAnno);
return val == null ? "":(String)val;
}
// System.out.println("获取类上的注解----------------->");
Annotation classAnno = AnnotationUtils.findAnnotation(pjp.getTarget().getClass(),AddBusiId.class);
Object val = AnnotationUtils.getValue(classAnno);
return val == null ? "":(String)val;
}
}