springboot aop

第一步:添加aop相关依赖

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

第二步:写自定义注解

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



@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MyAnnotation {
    String value() default "";

    String name() default "";
}

如上代码所示,该注解有两个属性,value和name

第三步:写切面逻辑

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.stereotype.Component;

import java.lang.reflect.Method;


@Aspect
@Component
public class AopAdvice {

    // 1.先写切点,对应注解(nomal.aop.MyAnnotation是自定义注解的位置)
    @Pointcut("@annotation(nomal.aop.MyAnnotation)")
    public void myPointcut(){}

    // 2.写切面的业务逻辑,myPointcut()是1中的方法名
    @Around("myPointcut()")
    public Object doAop(ProceedingJoinPoint joinPoint) throws Throwable {
        // 如果业务逻辑要用到注解上的属性值
        MyAnnotation annotation=getObject(joinPoint);

        // 写切面 前面的页面逻辑

		// 原本的业务
        Object result = joinPoint.proceed();

        // 写切面 后面的页面逻辑
        

        return result;
    }

    /**
     * 获取对应 注解的对象
     * @param joinPoint 切入点
     * @return 注解的对象
     * @throws Exception 异常
     */
    MyAnnotation getObject(ProceedingJoinPoint joinPoint) throws Exception {
        //1.1获取目标对象对应的字节码对象
        Class<?> targetCls=joinPoint.getTarget().getClass();

        //1.2获取目标方法对象
        //1.2.1 获取方法签名信息从而获取方法名和参数类型
        Signature signature=joinPoint.getSignature();
        //1.2.1.1将方法签名强转成MethodSignature类型,方便调用
        MethodSignature ms= (MethodSignature)signature;
        //1.2.2通过字节码对象以及方法签名获取目标方法对象
        Method targetMethod=targetCls.getDeclaredMethod(ms.getName(),ms.getParameterTypes());

        //1.3获取目标方法对象上注解中的属性值
        //1.2.3 获取方法上的自定义MyAnnotation 注解
        MyAnnotation annotation=targetMethod.getAnnotation(MyAnnotation.class);
        return annotation;
    }

举个栗子

假设我的业务逻辑是要输出某个方法的执行时间,并输出注解中的value和name
那么编辑切面逻辑可以如下:

@Around("myPointcut()")
public Object doAop(ProceedingJoinPoint joinPoint) throws Throwable {
    // 如果业务逻辑要用到注解上的属性值
    MyAnnotation annotation=getObject(joinPoint);

    // 切面 前面的页面逻辑
    System.out.println("切面->记录开始时间");
    long startTime = System.currentTimeMillis();

    // 原本的业务
    Object result = joinPoint.proceed();


    // 切面 后面的页面逻辑
    System.out.println("切面->记录结束时间");
    long endTime = System.currentTimeMillis();

    System.out.println("切面->本次业务用时:"+(endTime-startTime)+"ms");
    System.out.println("切面->value:"+annotation.value());
    System.out.println("切面->name:"+annotation.name());

    return result;
}

然后找个业务的方法上加上注解

@MyAnnotation(name = "测试",value = "666")
public void doExecute() throws Exception{
    System.out.println("业务逻辑开始");
    TimeUnit.SECONDS.sleep(3);
    System.out.println("业务逻辑结束");
}

当业务逻辑执行后,可以看到输出如下图所示
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值