当前位置: 移动技术网 > IT编程>开发语言>Java > SpringBoot项目中使用AOP的方法

SpringBoot项目中使用AOP的方法

2019年07月19日  | 移动技术网IT编程  | 我要评论

三人行采集器,职场英语学习,长虹彩电

本文介绍了springboot项目中使用aop的方法,分享给大家,具体如下:

1.概述

将通用的逻辑用aop技术实现可以极大的简化程序的编写,例如验签、鉴权等。spring的声明式事务也是通过aop技术实现的。

具体的代码参照 示例项目

spring的aop技术主要有4个核心概念:

pointcut: 切点,用于定义哪个方法会被拦截,例如 execution(* cn.springcamp.springaop.service.*.*(..))

advice: 拦截到方法后要执行的动作

aspect: 切面,把pointcut和advice组合在一起形成一个切面

join point: 在执行时pointcut的一个实例

weaver: 实现aop的框架,例如 aspectj 或 spring aop

2. 切点定义

常用的pointcut定义有 execution 和 @annotation 两种。execution 定义对方法无侵入,用于实现比较通用的切面。@annotation 可以作为注解加到特定的方法上,例如spring的transaction注解。

execution切点定义应该放在一个公共的类中,集中管理切点定义。

示例:

public class commonjoinpointconfig {
  @pointcut("execution(* cn.springcamp.springaop.service.*.*(..))")
  public void servicelayerexecution() {}
}

这样在具体的aspect类中可以通过 commonjoinpointconfig.servicelayerexecution()来引用切点。

public class beforeaspect {
  @before("commonjoinpointconfig.servicelayerexecution()")
  public void before(joinpoint joinpoint) {
    system.out.println(" -------------> before aspect ");
    system.out.println(" -------------> before execution of " + joinpoint);
  }
}

当切点需要改变时,只需修改commonjoinpointconfig类即可,不用修改每个aspect类。

3. 常用的切面

before: 在方法执行之前执行advice,常用于验签、鉴权等。

after: 在方法执行完成后执行,无论是执行成功还是抛出异常.

afterreturning: 仅在方法执行成功后执行.

afterthrowing: 仅在方法执抛出异常后执行.

一个简单的aspect:

@aspect
@component
public class beforeaspect {
  @before("commonjoinpointconfig.servicelayerexecution()")
  public void before(joinpoint joinpoint) {
    system.out.println(" -------------> before aspect ");
    system.out.println(" -------------> before execution of " + joinpoint);
  }
}

4. 自定义注解

假设我们想收集特定方法的执行时间,一种比较合理的方式是自定义一个注解,然后在需要收集执行时间的方法上加上这个注解。

首先定义一个注解tracktime:

@target({elementtype.method, elementtype.type})
@retention(retentionpolicy.runtime)
public @interface tracktime {
  string param() default "";
}

然后再定义一个aspect类,用于实现注解的行为:

@aspect
@component
public class tracktimeaspect {
  @around("@annotation(tracktime)")
  public object around(proceedingjoinpoint joinpoint, tracktime tracktime) throws throwable {
    object result = null;
    long starttime = system.currenttimemillis();
    result = joinpoint.proceed();
    long timetaken = system.currenttimemillis() - starttime;
    system.out.println(" -------------> time taken by " + joinpoint + " with param[" + tracktime.param() + "] is " + timetaken);
    return result;
  }
}

在某个方法上使用这个注解,就可以收集这个方法的执行时间:

@tracktime(param = "myservice")
public string runfoo() {
  system.out.println(" -------------> foo");
  return "foo";
}

注意 @tracktime(param = "myservice") 注解是可以传参的。

为了让注解可以传参数,需要在定义注解时指定一个参数string param() default "默认值",

同时在aspect类中,around方法上加上相应的参数,@around注解中也需要用参数的变量名tracktime,而不能用类名tracktime。

@around("@annotation(tracktime)")
public object around(proceedingjoinpoint joinpoint, tracktime tracktime)

5.总结

在运行示例项目时,控制台会输出以下内容:

 -------------> before aspect
 -------------> before execution of execution(string cn.springcamp.springaop.service.myservice.runfoo())
 -------------> foo
 -------------> time taken by execution(string cn.springcamp.springaop.service.myservice.runfoo()) with param[myservice] is 8
 -------------> after aspect
 -------------> after execution of execution(string cn.springcamp.springaop.service.myservice.runfoo())
 -------------> afterreturning aspect
 -------------> execution(string cn.springcamp.springaop.service.myservice.runfoo()) returned with value foo

可以看出几种 aspect 的执行顺序依次为 before after around afterreturning(afterthrowing)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网