Spring AOP

目录

AOP

为什么使用AOP

Spring AOP

AOP的组成

 实现Spring AOP

 AOP表达式

Spring AOP的实现原理

在介绍Spring AOP之前需要先介绍AOP

AOP

AOP(面向切面编程)就像我们之前学习的OOP(面向对象编程)它是一种思想,它是对某一类事情的集中处理,比如用户登录的校验,在没学AOP之前,需要判断用户是否登录的页面都需要各自实现用户验证的方法,然而在有了AOP之后我们只需要在某处配置,所有需要验证判断用户登录状态的页面就可以实现用户登录验证了,不需要每个方法都写相同的用户验证了

为什么使用AOP

在上面我举出登录校验的例子,如果没使用AOP那么所有需要登录校验的地方都需要进行判断,此时代码的维护成本就会越来越高,对于这种功能统⼀,且使用的地方较多的功能就需要使用AOP来统一处理

除了统一用户登录判断之外AOP还有其他作用

1.统一日志记录

2.统一方法执行时间统计

3.统一异常处理

4.统一的返回格式设置

5.事务的开启和提交等

可以说使用AOP是扩充多个对象的某个能力,所以AOP是OOP的补充和完善

Spring AOP

我们知道AOP是思想而Spring AOP则是Spring 公司对于AOP实现的具体方案

AOP的组成

1.切面(Aspect) : 定义AOP业务类型的(当前AOP是干嘛的)

2.连接点(Join Point): 程序中有可能调用AOP的地方就叫做一个连接点

3.切点(Pointcut): 定义AOP的拦截规则

4.通知(Advice): [增强方法] 定义什么时候做什么事

        a.前置通知:拦截的目标方法之前执行的通知

        b.后置通知:拦截的目标方法之后执行的通知

        c.返回之后通知:拦截的目标方法返回数据之后的通知

        d.抛出异常之后通知:拦截的目标方法抛出异常之后执行的通知

        e.环绕通知:拦截的目标方法执行前后都会执行的通知

基础知识介绍比较难懂,我画图介绍方便理解

Spring AOP_第1张图片

 实现Spring AOP

1.添加Spring AOP框架支持


 org.springframework.boot
 spring-boot-starter-aop

2.定义切面和切点

@Component
@Aspect //标识当前类为切面
public class LoginAOP {
    //定义切点(拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
    }
}

3.定义通知

//前置通知
    @Before("pointcut()")
    public void before() {
        System.out.println("执行了前置通知");
    }

 以上三步就是最基础的Spring AOP使用,下面检验一下效果

Spring AOP_第2张图片

 可以看到通过切点定义的拦截规则成功拦截到UserController包下的类并执行了前置方法

//环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {//参数是默认的代表正在执行的目标方法
        Object result=null;
        System.out.println("Around方法开始执行");
        try {
            result=joinPoint.proceed();//执行的目标方法
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("Around方法执行完成");
        return result;
    }

前面的四种通知都是方便理解的,这里强调环绕通知的使用,首先方法有参数代表要执行的目标方法

并且有返回值,其次就是通过joinPoint.proceed()方法执行目标方法,但不代表返回值是目标方法的返回值而是当前执行的目标方法

Spring AOP_第3张图片

 环绕通知执行最早结束最晚,在之中执行各种通知方法

 AOP表达式

Spring AOP_第4张图片

Spring AOP的实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截

Spring AOP_第5张图片

 可以看到在没有代理类时我们是直接调用目标对象,当出现了代理之后就需要先经过代理才能调用目标对象,根据代理类产生的时机就可分为动态代理或者静态代理,我们学习的Spring AOP就是基于动态代理

Spring AOP支持 JDK Proxy 和 CGLIB 方式实现动态代理,当目标对象实现了接口就会使用JDK提供的Proxy ,当没有实现接口则基于CGLIB生成代理类

你可能感兴趣的:(spring,java,spring,boot)