Aspectj实战教程

概念

Advice通知

注入到class文件中的代码。典型的 Advice 类型有 before、after 和 around,分别表示在目标方法执行之前、执行后和完全替代目标方法执行的代码。 除了在方法中注入代码,也可能会对代码做其他修改,比如在一个class中增加字段或者接口。

Joint point(连接点)

程序中可能作为代码注入目标的特定的点,例如一个方法调用或者方法入口。

Pointcut(切入点)

告诉代码注入工具,在何处注入一段特定代码的表达式。例如,在哪些 joint points 应用一个特定的 Advice。切入点可以选择唯一一个,比如执行某一个方法,也可以有多个选择。

实战(springboot整合aspectj)

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

通知类型

  • Before前置通知

    在切入点前面执行通知。

  • After后置通知

    在切入点方法执行后通知,如果切入点的方法抛出异常,也会进行通知。

  • Around环绕通知

    可以在切入点前,切入点后进行通知。可以自定义切入点方法执行前或后执行指定代码。可以用于统计方法执行时间。

  • AfterReturning后置通知

    抛出异常不会进行通知,方法正常返回才会进行通知。

  • AfterThrowing异常通知

    抛出异常后进行通知。

代码

// 普通类
@Service
public class AspectService {
    @ShowRunTime
    public void HelloAspectj(String name) {

    }

    //@AdminSaid
    @ShowRunTime
    public void said() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
// 自定义的注解

// 标明该注解可以标注在什么位置上
@Target({ElementType.METHOD,ElementType.FIELD})
// 标明该注解可以保留到什么时候
@Retention(RetentionPolicy.RUNTIME)
// 是否在javadoc中可用
@Documented
public @interface AdminSaid {
}
// 自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ShowRunTime {

}
/**
 * 这是一个用于配置切面通知的类
 * @Configuration:标明配置类,将切面注入到spring中
 * @Aspect:标明一个切面类
 */
@Configuration
@Aspect
public class AnAspect {

    // 前置通知:execution(返回值类型 包名.方法名(方法参数))
    @Before(value = "execution(* com.sundae.test.springbootdemo.aspectjdemo.AspectService.HelloAspectj(..))")
    public void showToast(JoinPoint joinPoint) {
        // 通过joinpoint获取参数
        Object[] args = joinPoint.getArgs();
        System.out.println("通过joinpoint获取参数"+args[0]);

        // 通过joinpoint获取joinpoint的类型
        System.out.println("通过joinpoint获取joinpoint的类型"+joinPoint.getKind());

        Signature signature = joinPoint.getSignature();
        System.out.println("方法名"+signature.getName());

        System.out.println(joinPoint.getTarget());

    }

    // 创建一个注解为AdminSaid的切面。
    @Pointcut("@annotation(com.sundae.test.springbootdemo.aspectjdemo.AdminSaid)")
    public void pointcut() {

    }

    // 前置通知:在上面切面pointcut()之前进行通知。
    @Before("pointcut()")
    public void showT() {
        System.out.println("AdminSaid!");
    }

    // 创建一个注解为ShowRunTime的切面。
    @Pointcut("@annotation(com.sundae.test.springbootdemo.aspectjdemo.ShowRunTime)")
    public void runTimePointCut() {

    }

    // 创建上面切面的环绕通知。实现了所有添加注解@ShowRunTime的方法都能打印方法运行时间的功能。
    // ProceedingJoinPoint:连接点。
    @Around("runTimePointCut()")
    @AfterThrowing
    public void showRunTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long before = new Date().getTime();
        joinPoint.proceed();
        long after = new Date().getTime();
        // joinPoint.getSignature().getName()获取方法名称。
        System.out.println(joinPoint.getSignature().getName()+"方法运行时间:"+(after-before)+"ms");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值