AOP面向切面编程

AOP简介

AOP(Aspect oriented Programming)面向切面编程,就是面向特定的方法编程,将方法比作一个一个的切面,可以向指定的方法执行前/后执行自己的逻辑。如统一获取方法的时间。

应用场景:
记录操作日志、权限控制、事务管理

优势:
代码无侵入(无需在原先的代码上修改)、减少重复代码、提高开发效率、维护方便

原理:

动态代理,运行时会注入一个动态代理对象(实现了注入的接口),动态代理对象会先后执行切片前的方法、调用方法、切片后的方法。
在动态代理时的userMapper:
AOP面向切面编程_第1张图片

核心概念

JoinPoint(连接点):能够被控制的方法,在spring中指方法的运行,含有方法执行时的相关信息。
Advice(通知):指重复、相同的功能,即共性功能。
PointCut(切入点):匹配连接的条件,实际被AOP控制的方法,通知只有在切入点方法执行时被应用。
Aspect(切面):描述通知和切入点的对应关系
target(目标对象):通知所应用的对象。

使用方式:
1.创建切面类 标记注解@Aspect @Component
2.创建切面方法参数为ProceedingJoinPoint(连接点),在方法上加入@Around注解表明该切面在哪个方法调用时执行。

切入点表达式:
  @Around("execution(* com.yi.springbootwebquickstart.controller.*.*(..))")  
  第一个*表示任意返回值,第二个*表示controller包下的任意类,第三个*表示类中的任意方法 
  根据自定义注解匹配:
  @Around(@annotation(com.yi.springbootwebquickstart.aop.mylog))
@Component
@Aspect
@Slf4j
public class TimeAspect {
    @Around("execution(* com.yi.springbootwebquickstart.controller.*.*(..))")
    public void recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long begin = System.currentTimeMillis();

        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();

        log.info("{} cost time:"+(end-begin),joinPoint.getSignature());
    }
}

通知

1.通知类型

@Around 环绕通知,在目标方法执行前后执行
@Before 前置通知,在目标方法执行前执行
@After 后置通知,在目标方法执行后执行,有异常也会执行
@AfterReturning 返回后通知,在目标方法返回后执行,有异常不会执行
@AfterThrowing 异常后通知,在目标方法发生异常后执行


@Component
@Aspect
@Slf4j
public class TimeAspect {
	//定义一个方法,将相同的切入点表达式抽出出来
    @Pointcut("execution(* com.yi.springbootwebquickstart.controller.*.*(..))") 
    public void pt(){}
    @Around("pt()")
    public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long begin = System.currentTimeMillis();

        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();

        log.info("{} cost time:"+(end-begin),joinPoint.getSignature());
        return result;
    }

    @Before("pt()")
    public void before(){
        System.out.println("before");
    }

    @After("pt()")
    public void after(){
        System.out.println("after");
    }
    @AfterReturning("pt()")
    public void afterReturning(){
        System.out.println("afterReturning");
    }
    
    @AfterThrowing("pt()")
    public void afterThrowing(){
        System.out.println("afterThrowing");
    }
}

2.通知顺序

默认是按照类名以环绕顺序来执行,字母越靠前:通知前方法越先执行,通知后方法越后执行。
AOP面向切面编程_第2张图片
可以加入在类名上加入@Order(int) 来控制执行顺序,数字越小通知前方法越先执行,通知后方法越后执行。

连接点:可以被AOP控制的方法

在Spring中特指方法的运行,可以通过连接点获取方法执行时的相关信息,如类名、方法名、方法参数等。
@Around通知只能用ProceedingJoinPoint,其他通知只能用JointPoint

log.info("目标方法的类名:{}",joinPoint.getTarget().getClass().getName());
log.info("目标方法签名:{}",joinPoint.getSignature());
log.info("目标方法方法名:{}",joinPoint.getSignature().getName());
log.info("运行参数:{}",joinPoint.getArgs());

你可能感兴趣的:(Springboot,开发语言,spring,boot,aop)