各个注解方法执行顺序
@Around注解方法的前半部分业务逻辑->@Before注解方法的业务逻辑->目标方法的业务逻辑
->@Around注解方法的后半部分业务逻辑(@Around注解方法内的业务逻辑若对ProceedingJoinPoint.proceed()方法没做捕获异常处理,直接向上抛出异常,则不会执行Around注解方法的后半部分业务逻辑;若做了异常捕获处理,则会执行)。
->@After(不管目标方法有无异常,都会执行@After注解方法的业务逻辑)
->@AfterReturning(若目标方法无异常,执行@AfterReturning注解方法的业务逻辑)
->@AfterThrowing(若目标方法有异常,执行@AfterThrowing注解方法的业务逻辑)
环绕通知@Around使用
- /**
- * 此方法必须有返回值,否则目标方法无法拿到执行结果
- * @param point
- * @return
- */
- @Around("execution(* com.test.resultFacade..*(..))")
- public Object checkContactInfoUpdateBefore(ProceedingJoinPoint point){
- log.info("目标方法前执行");
- Object result = null;
- try {
- // 执行目标方法
- result = point.proceed();
- log.info("result:",JSONObject.toJSONString(result));
- } catch (Throwable throwable) {
- throwable.printStackTrace();
- }
- log.info("目标方法后执行");
- return result;
- }
aspect各个方法的使用案例说明
- @Aspect
- @Slf4j
- public class MessageAspect {
-
- /**
- * 方式一:使用表达式,满足此注解的方法即会执行切面方法
- * 1.本类引用
- * 2.其他的切面引用
- */
- @Pointcut("execution(public Integer com.xiaoz.aop.calculator.dev(int,int))")
- public void poincut(){
-
- }
-
- /**
- * 方式二:使用主键方式,标注此注解的方法即会执行切面方法
- * 1.本类引用
- * 2.其他的切面引用
- */
- @Pointcut("@annotation(com.xiaoz.annotation.MessageAnnotation)")
- public void pointcut() {
- }
-
- /**
- * around切面方法,引用本类中的公用的pointcut
- * @param point
- * @return
- * @throws Throwable
- */
- @Around("Pointcut()")
- public Object process(ProceedingJoinPoint point) throws Throwable {
- System.out.println("@Around:执行目标方法之前...");
- //访问目标方法的参数:
- Object[] args = point.getArgs();
- if (args != null && args.length > 0 && args[0].getClass() == String.class) {
- args[0] = "改变后的参数1";
- }
- //用改变后的参数执行目标方法
- Object returnValue = point.proceed(args);
- System.out.println("@Around:执行目标方法之后...");
- System.out.println("@Around:被织入的目标对象为:" + point.getTarget());
- return "原返回值:" + returnValue + ",这是返回结果的后缀";
- }
-
- /**
- * 引用其他外部切面类的切入点公用方法
- */
- @After(com.xiaoz.other.LogAspect.pointCut())
- public void logEnd(){
- log.info("执行代码");
- }
-
- @Before("execution(* com.abc.service.*.many*(..))")
- public void permissionCheck(JoinPoint point) {
- System.out.println("@Before:模拟权限检查...");
- System.out.println("@Before:目标方法为:" +
- point.getSignature().getDeclaringTypeName() +
- "." + point.getSignature().getName());
- System.out.println("@Before:参数为:" + Arrays.toString(point.getArgs()));
- System.out.println("@Before:被织入的目标对象为:" + point.getTarget());
- }
-
- /**
- * 在所有标记了@SMSAndMailSender的方法中切入
- * @param joinPoint
- * @param result
- */
- @AfterReturning(value="@annotation(com.trip.demo.SMSAndMailSender)", returning="result")
- public void afterReturning(JoinPoint joinPoint , Object result//注解标注的方法返回值) {
- MethodSignature ms = (MethodSignature) joinPoint.getSignature();
- Method method = ms.getMethod();
- boolean active = method.getAnnotation(SMSAndMailSender.class).isActive();
- if (!active) {
- return;
- }
- String smsContent = method.getAnnotation(SMSAndMailSender.class).smsContent();
- String mailContent = method.getAnnotation(SMSAndMailSender.class).mailContent();
- String subject = method.getAnnotation(SMSAndMailSender.class).subject();
- }
-
- /**
- * 在抛出异常时使用 SMSAndMailSender为自定义注解,所有标注此注解的业务方法都会触发此切面方法
- * @param joinPoint
- * @param ex
- */
- @AfterThrowing(value="@annotation(com.xiaoz.SMSAndMailSender)",throwing = "ex")
- public void afterThrowing(JoinPoint joinPoint, Throwable ex//注解标注的方法抛出的异常) {
- MethodSignature ms = (MethodSignature) joinPoint.getSignature();
- Method method = ms.getMethod();
- String subject = method.getAnnotation(SMSAndMailSender.class).subject();
- }
-
- }
- @Target({ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface MessageAnnotation {
- InteractionTopicEnum value();
- }
自定义枚举类
- @Getter
- @AllArgsConstructor
- public enum InteractionTopicEnum {
-
- ORDER(1, "下单完成"),
- ORDER_PAY(2, "支付完成"),;
-
- private Integer key;
- private String value;
- }
业务方法标注切面方法
- @Transactional
- @MessageAnnotation(InteractionTopicEnum.ORDER)
- public BaseDtoResponse
creatOrder(){ - // 执行业务代码
- }
切面类方法
- @Aspect
- @Slf4j
- public class MessageAspect {
- @Pointcut("@annotation(com.xiaoz.annotation.MessageAnnotation)")
- public void pointcut() {
- }
-
- @Before("pointcut()")
- public void permissionCheck(JoinPoint point) {
- // 执行切入方法
- }
- }