Spring—aop使用整理

Posted zqq_hello_world

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring—aop使用整理相关的知识,希望对你有一定的参考价值。

SpringAop使用

前置通知

/**
 * 前置通知 , 进入方法前进入切面
 * @param joinPoint
 */
//@Before("execution(* com.example.demo.service.impl.TestServiceImpl.*(..))")
@Before("execution(* com.example.demo.service.impl.TestServiceImpl.printTest(String))")
public void beforeAdvise(JoinPoint joinPoint){
    //获取request ,在request获取参数(http请求传的参数)
    HttpServletRequest request = ServletUtil.getRequest();
    Map<String,String[]> map = request.getParameterMap();
    for(Map.Entry<String,String[]> entry:map.entrySet()){
        String name = entry.getKey();
        String[] strs = entry.getValue();
        Arrays.stream(strs).forEach(s -> {
            System.out.println("参数:" + name + "=" + s);
        });
    }
    //切面方法的参数
    Object[] objects = joinPoint.getArgs();
    Arrays.stream(objects).forEach(o -> {
        if(o instanceof String){
            System.out.println("string类型参数:" + o);
        }
    });
    System.out.println("前置通知===线程:" + Thread.currentThread().getName());
}

环绕通知

/**
 * 环绕通知,前后进入切面,通过代理,可阻断方法执行和返回
 * @param joinPoint
 */
@Around("execution(* com.example.demo.service.impl.TestServiceImpl.printTest(String))")
public String around(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("环绕通知-start:" +Thread.currentThread().getName());
    String result = (String) joinPoint.proceed();
    System.out.println("环绕通知-end:" +Thread.currentThread().getName());
    return result;
}

后置通知

/**
 * 后置通知,在目标方法执行后执行,不能获取方法的执行结果
 */
@After("execution(* com.example.demo.service.impl.TestServiceImpl.printTest(String))")
public void after(JoinPoint joinPoint){
    String name = joinPoint.getSignature().getName();
    System.out.println("后置通知-start:" +Thread.currentThread().getName() + "; " + name);
}

返回后通知

/**
 * 返回后通知,用returning获取返回值
 * @param point
 * @param result 等于returning的值
 */
@AfterReturning(value = "execution(* com.example.demo.service.impl.TestServiceImpl.printTest(String))",returning = "result")
public void afterReturning(JoinPoint point,String result){
    System.out.println("返回后通知-start:" +Thread.currentThread().getName() + "; " + result);
}

异常通知

/**
 * 异常通知
 * @param ex 等于throwing
 */
  @AfterThrowing(value = "execution(* com.example.demo.service.impl.TestServiceImpl.printTest(String))",throwing = "ex")
public void afterThrowing(Throwable ex){
    System.out.println("异常通知:" + Thread.currentThread().getName());
    ex.printStackTrace();
}

Aop切自定义注解

  1. 自定义注解

    /**
     * 自定义注解,切面切点切这个注解
     * @author zqq
     * @date 2021/5/10 11:33
     */
    @Documented
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LogAnnotation {
    
        String value() default "";
    }
    
  2. 定义切面类

    /**
     * aop切面切自定义注解
     * @author zqq
     * @date 2021/5/10 11:44
     */
    @Aspect //切面
    @Component  //spring扫描,注册成spring的bean
    public class LogAspect {
    
        /**
         * 切注解,实现简单日志记录
         * @param joinPoint
         */
        @Before(value = "@annotation(com.example.demo.annotation.LogAnnotation)")
        public void before(JoinPoint joinPoint){
            try {
                HttpServletRequest request = ServletUtil.getRequest();
                Map<String, String[]> map = request.getParameterMap();
                //打印普通参数
                for(Map.Entry<String,String[]> entry : map.entrySet()){
                    String name = entry.getKey();
                    for(String val : entry.getValue()){
                        System.out.println("请求参数:" + name + "=" + val);
                    }
                }
                //获取注解
                LogAnnotation annotation = getDeclaredAnnotation(joinPoint);
                System.out.println("annotation.value = "+ annotation.value());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 获取方法上固定的注解
         * @param joinPoint
         * @return
         * @throws NoSuchMethodException
         */
        private LogAnnotation getDeclaredAnnotation(JoinPoint joinPoint) throws NoSuchMethodException {
            String methodName = joinPoint.getSignature().getName();//获取方法名称
            Class<?> targetClass = joinPoint.getTarget().getClass();//获取类类型
            Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();//获取参数
            Method objMethod = targetClass.getMethod(methodName, parameterTypes);//获取方法
            return objMethod.getDeclaredAnnotation(LogAnnotation.class);//返回方法的ReportLog注解
        }
    }
    

Spring-Web项目中获取Request\\Response

/**
 *  在spring web RequestAttributes获取request/response,本质是存放在ThreadLocal(线程副本)中,然后取出
 * @author zqq
 * @date 2021/5/10 13:34
 */
public class ServletUtil {

    /**
     * 获取Request
     * @return
     */
    public static HttpServletRequest getRequest(){
        return getServletRequestAttributes().getRequest();
    }

    /**
     * 获取Response
     * @return
     */
    public static HttpServletResponse getResponse(){
        return getServletRequestAttributes().getResponse();
    }

    /**
     * 公共代码部分获取ServletRequestAttributes
     * @return
     */
    private static ServletRequestAttributes getServletRequestAttributes(){
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) requestAttributes;
    }
}

代码地址

Giteehttps://gitee.com/zhaoqingquan/springaop

以上是关于Spring—aop使用整理的主要内容,如果未能解决你的问题,请参考以下文章

spring AOP 整理

Spring AOP整理

Spring aop学习整理(spring in action):spring AOP

spring面试整理

spring面试整理

spring面试整理