Spring Boot实际项目用简单的AOP

栏目: Java · 发布时间: 6年前

内容简介:将通用的逻辑用AOP技术实现可以极大的简化程序的编写,例如1.Pointcut: 切点,用于定义哪个方法会被拦截,例如2.Advice: 拦截到方法后要执行的动作

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

Spring的AOP技术主要有4个核心概念:

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

2.Advice: 拦截到方法后要执行的动作

3.Aspect: 切面,把 PointcutAdvice 组合在一起形成一个切面

4.Join Point: 在执行时 Pointcut 的一个实例

5.Weaver: 实现AOP的框架,例如 AspectJSpring 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.常用的切面

1.Before: 在方法执行之 执行 Advice ,常用于 验签、鉴权 等。

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

3.AfterReturning: 仅在方法执行 成功后 执行.

4.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)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML5

HTML5

Matthew David / Focal Press / 2010-07-29 / USD 39.95

Implement the powerful new multimedia and interactive capabilities offered by HTML5, including style control tools, illustration tools, video, audio, and rich media solutions. Understand how HTML5 is ......一起来看看 《HTML5》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码