Spring AOP - 自定义注解实现共性需求

Spring AOP可以帮助我们Java在不修改源代码的前提下实现功能增强,其底层实现基于JDK动态代理或者CGlib。

以往使用execution选定具体利用AOP扩展那些类,非常不灵活。

现在我们可以使用自定义注解实现AOP满足共性需求。

项目结构

一、新建SpringBoot 2.x项目,在pom文件中引入依赖

        <!--Spring切面类底层的依赖-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>
        <!--用来打印日志-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
        <!--JSON序列化-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

二、构建自定义注解

自定义注解是一个标识符,用来指定哪一个方法可以进行扩展,所以注解类里不需要有任何实现。

代码如下:

//注解的作用目标,表示该注解用在方法上
@Target(ElementType.METHOD)
//注解的保留时间,表示注解在运行时保留
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodExporter {
}

@interface:用来说明是个注解类

三、开发切面类

代码如下:

//说明当前对象是个切面
@Aspect
//将当前对象交给Spring IOC实例化并管理
@Component
//用于打印日志
@Slf4j
public class MethodExporterAspect {

    //@Around环绕通知,最强大的通知类型,可以控制方法入参、执行、返回结果等各方面细节
    //里面的表达式@annotation用来说明某个方法上书写了MethodExporter注解的话就会执行下面的方法
    //对目标方法进行增强
    @Around("@annotation(com.doll.aopanno.annoation.MethodExporter)")
    public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable{
        long st = System.currentTimeMillis();
        //joinPoint:连接点;执行目标方法,获取返回值; proceed:继续进行
        Object proceed = joinPoint.proceed();
        long et = System.currentTimeMillis();

        ObjectMapper mapper = new ObjectMapper();
        //将入参JSON序列化
        String jsonParam = mapper.writeValueAsString(joinPoint.getArgs());
        //将返回结果JSON序列化
        String jsonResult = null;
        if (proceed!=null){
            jsonResult = mapper.writeValueAsString(proceed);
        }else {
            jsonResult = "null";
        }
        //模拟上报过程
        log.info("正在上报服务器调用过程:\ntarget:{}.{}()\nexecution:{}ms,\nparameter:{}\nresult:{} "
        ,joinPoint.getTarget().getClass().getSimpleName()
        ,joinPoint.getSignature().getName()
        ,(et-st)
        ,jsonParam
        ,jsonResult);

        return proceed;
    }
}

四、测试自定义注解

在目标方法上增加自定义注解

代码如下:

@RestController
public class SampleController {

    @MethodExporter
    @GetMapping("/list")
    public Map list(int page, int rows) {
        Map result = new LinkedHashMap();
        result.put("code", 0);
        result.put("message", "success");
        
        try {
            Thread.sleep(new Random().nextInt(1000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }
}

如果你是idea2020以后的版本应该可以看见@GetMapping注解括号里有一个地球图标,点击,然后选择在HTTP客户端中打开。

###写入参数,然后点击左侧运行绿色箭头,运行/调试 HTTP请求
GET http://localhost:8080/list?page=1&rows=100 

可以看到输出结果,成功使用AOP+自定义注解的方式增强方法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值