spring aop拦截指定方法和自定义注解

1、使用aop需要加入maven依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
   <version>2.0.0.RELEASE</version>
</dependency>

2、aop拦截指定方法
拦截getById方法:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class UserServiceAspect {

    //拦截指定的方法
    @Pointcut("execution(* com.zengqingfa.demo.service.impl.UserServiceImpl.getById(..))")
    private void getByIdPointCut() {
    }

    @Around("getByIdPointCut()")
    public Object getByIdAround(ProceedingJoinPoint pjp) throws Throwable {
        //获取参数
        Object[] args = pjp.getArgs();
        System.out.println("参数args:" + args[0]);
        //执行方法前
        Object returnVal = null;
        //执行方法
        try {
            Long start = System.currentTimeMillis();
            returnVal = pjp.proceed();
            //执行方法后
            System.out.println("执行了:" + (System.currentTimeMillis() - start) + "s");
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return returnVal;
    }
}

3、aop拦截指定注解
拦截AspectAnnotation,进行一个方法执行时间的打印。
如果isStart 参数为true,则进行时间的打印
1)注解:

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

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AspectAnnotation {

    boolean isStart() default false;
    
}

2)方法

@Override
@AspectAnnotation(isStart = true)
public SysUser getById(Long id) {
    return sysUserMapper.selectByPrimaryKey(id);
}

3)拦截:

package com.zengqingfa.demo.aop;

import com.zengqingfa.demo.annotation.AspectAnnotation;
import org.apache.ibatis.binding.MapperMethod;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Component
@Aspect
public class AspectAnnotationAop {

@Pointcut("@annotation(com.zengqingfa.demo.annotation.AspectAnnotation)")
    private void annotationPointCut() {
    }

    @Around("annotationPointCut()")
    public Object annotationAround(ProceedingJoinPoint jp) throws Throwable {
        //获取方法
        Method method = ((MethodSignature) jp.getSignature()).getMethod();
        // 获取AspectAnnotation注解
        AspectAnnotation aspectAnnotation = method.getAnnotation(AspectAnnotation.class);
        boolean flag = aspectAnnotation.isStart();
        //执行方法前
        Object returnVal = null;
        try {
            if (flag) {//如果为true,则计算方法的时间
                Long start = System.currentTimeMillis();
                returnVal = jp.proceed();
                //执行方法后
                System.out.println("执行了:" + (System.currentTimeMillis() - start) + "s");

            } else {//否则不计算
                returnVal = jp.proceed();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return returnVal;
    }
}

4、表达式

 切入点表达式:
    语法:
                   访问修饰符(可选)     返回值类型(必须)         包名类名(可选)    方法(必须)  参数
        execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
            throws-pattern?)

     1. 完整写法: 拦截UserServiceImpl类的save()方法,无参
        execution(public * com.zengqingfa.service.impl.UserServiceImpl.save())
     2. 省略修饰符
        execution(* com.zengqingfa.service.impl.UserServiceImpl.save())
     3. 包名用*号,类名也用*号
        execution(* *.*.*.*.*.save())
     4. 拦截指定包及其子包下的UserServiceImpl类的所有save方法
        execution(* com..UserServiceImpl.save())
     5. 拦截所有serviceImpl结尾的类的所有无参方法
        execution(* com..*ServiceImpl.*())
     6. (常用)拦截所有serviceImpl结尾的类的所有方法,参数任意
        execution(* com..*ServiceImpl.*(..))  参数任意,可有可无
        execution(* com..*ServiceImpl.*(*))  参数任意,必须有参数
     7. 拦截所有的save开头的方法
        execution(* save*(..))
     8. 拦截所有的save开头的方法,或者update开头的方法
        expression="execution(* save*(..)) || execution(* update*(..))
        expression="execution(* save*(..)) or execution(* update*(..))
     9. 不拦截save开头的方法
        expression="!execution(* save*(..))"
        expression=" not execution(* save*(..))
     10.拦截容器中指定的bean
        expression="bean(userService)" 拦截容器中userService类中的所有方法
        expression="bean(*Service)"   拦截容器中Service结尾的类中的所有方法

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值