Spring AOP(JavaEE进阶系列5)

目录

前言:

[1.什么是Spring AOP](#1.什么是Spring AOP)

2.为什么要使用AOP呢?

3.AOP的组成

3.1切面

3.2切点

3.3通知

3.4连接点

[4.Spring AOP的实现](#4.Spring AOP的实现)

4.1添加依赖

4.2定义切面

4.3定义切点

4.4实现通知

5.AOP的实现原理

结束语:


前言:

在上一节中小编主要是于大家分享了有关于MyBatis的一些基础知识,让大家了解了有关于如何将数据库和我们的程序进行关联,那么接下来我们就来一起来学一下有关于AOP的一些知识,在Spring中一般提到的就是IoC和AOP,那么之前的学习中也给大家介绍了有关于IoC容器的一些基础知识,那么接下来小编将会带着大家一起来学习有关于AOP的一些基础知识。这节中小编将主要介绍有关于AOP的组成,概念,学习Spring AOP的使用以及Spring AOP的实现原理。

1.什么是Spring AOP

在介绍Spring AOP之前,首先我们需要了解一下什么是AOP?

**AOP(Aspect Oriented Programming):面向切面编程,它是一种思想,它是对某一类事情的集中处理。**比如用户登录权限的校验,没学AOP之前,我们所有需要判断用户登录的页面(中的方法),都要各自实现或调用用户验证的方法,然而有了AOP之后,我们只需要在某一处配置一下,所有需要判断用户登录页面中的方法就全部可以实现用户登录验证了,不再需要每个方法中都写相同的用户登录验证了。

**那么对于AOP与Spring AOP之间的关系就是:**AOP是一种思想,而Spring AOP是一个框架,提供了一种对AOP思想的实现,它们的关系和IoC与DI类似。

2.为什么要使用AOP呢?

想象⼀个场景,我们在做后台系统时,除了登录和注册等几个功能不需要做⽤户登录验证之外,其他几乎所有⻚⾯调⽤的前端控制器( Controller)都需要先验证⽤户登录的状态,那这个时候我们要怎么处理呢?
我们之前的处理⽅式是每个 Controller 都要写⼀遍⽤户登录验证,然⽽当你的功能越来越多,那么你要 写的登录验证也越来越多,⽽这些⽅法⼜是相同的,这么多的⽅法就会代码修改和维护的成本。那有没有简单的处理⽅案呢?答案是有的,对于这种功能统⼀,且使⽤的地⽅较多的功能,就可以考虑 AOP 来统⼀处理了。
除了统⼀的⽤户登录判断之外,AOP 还可以实现:

  • 统⼀⽇志记录
  • 统⼀⽅法执⾏时间统计
  • 统⼀的返回格式设置
  • 统⼀的异常处理
  • 事务的开启和提交等

也就是说使⽤ AOP 可以扩充多个对象的某个能力,所以 AOP 可以 说是 OOP(Object Oriented
Programming,⾯向对象编程)的补充和完善。

3.AOP的组成

3.1切面

切面(Aspect):它是定义事件(表明AOP是做啥的)。比如现在要做一个用户的登录校验。他就像是一个公司的老板一样来定义公司的方向。

3.2切点

切点(Pointcut):它是用来定义具体规则的。在上面切面明确了要做的是用户的登录校验之后接下来就由切点来定义用户登录拦截规则,哪些接口判断用户登录权限。哪些不判断。就像是公司中的中层领导人一样制定一份具体的方案。

3.3通知

通知(Advice):AOP执行的具体方法。在前俩个的基础之上方向明确,方案已经制定好之后,那么接下来就需要实施了,获取用户登录的信息,如果获取到说明已经登录,否则未登录。他就是公司的底层,用来负责具体业务的执行。

在Spring切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件之后会通知本方法进行调用:

  • 前置通知: 使用**@Before**,通知方法会在目标方法调用之前执行。
  • 后置通知: 使用**@After**,通知方法会在目标方法返回或者抛出异常后调用。
  • 返回通知: 使用**@AfterReturning**,通知方法会在目标方法返回后调用。
  • 异常通知: 使用**@AfterThrowing**,通知方法会在目标方法抛出异常之后调用。
  • 环绕通知: 使用**@Around**,通知包裹了被通通知的方法,在被通知的方法之前和调用方法之后执行自定义的行为。

3.4连接点

连接点( Join Point):有可能触发切点的所有点。比如说是在登录功能中会触发登录功能的所有接口。
AOP整个组成部分的概念如下图所示:

4.Spring AOP的实现

先来定义一个UserController。

java 复制代码
package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/getuser")
    public String getUser() {
        System.out.println("do getUser");
        return "get user";
    }

    @RequestMapping("/deluser")
    public String delUser() {
        System.out.println("do delUser");
        return "del user";
    }
}

4.1添加依赖

在pom.xml中添加如下配置。

java 复制代码
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

4.2定义切面

4.3定义切点

4.4实现通知


当我们输入一下url的时候:

就会在控制台中输出前置通知。

当加上后置通知的时候就会如下所示:

后置通知的代码:

此时在输入url之后的效果就是:

那么如果加的是环绕通知的效果呢?

环绕通知的代码如下所示:

执行结果如下所示:

那么如果没有上述的这些拦截的话,在实现过程当中就不会执行任何其他操作,比如我们现在定义一个ArticleController,如下所示:

java 复制代码
package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/art")
public class ArticleController {
    @RequestMapping("/getart")
    public String getArticle(){
        System.out.println("do getArticle");
        return "getArticle";
    }
}

当我们在访问的是后台就只会执行它本身要执行的方法。

5.AOP的实现原理

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

Spring AOP ⽀持 JDK ProxyCGLIB⽅式实现动态代理。默认情况下,实现了接⼝的类,使用 AOP 会基于 JDK ⽣成代理类,没有实现接⼝的类,会基于 CGLIB ⽣成代理类。

Spring 动态代理的组成:

  • JDK Proxy:代理对象必须实现接口,才能使用JDK Proxy。
  • CGLIB:通过实现代理类的子类来实现动态代理,注意被final修饰的类是不能够被代理的。

JDK Proxy 与 CGLIB的区别:

  • 出生不同。
  • **实现不同:**JDK Proxy要求代理类实现接口才能实现代理;而CGLIB是通过实现代理类的子类来完成动态代理的。
  • **性能不同:**JDK& + JDK Proxy性能是略高于CGLIB;JDK7之前CGLIB性能高于JDK Proxy。

结束语:

好了这节小编就给大分享到这里啦,希望这节对大家有关于Spring AOP的基础知识的了解有一定帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

相关推荐
一切皆有迹可循1 小时前
IntelliJ IDEA中Spring Boot项目整合MyBatis:从零实现高效数据持久化
java·spring boot·intellij-idea·mybatis
字节源流2 小时前
【微服务】基础概念
后端·spring·spring cloud
雾月552 小时前
LeetCode 941 有效的山脉数组
java·开发语言·数据结构·算法·leetcode·职场和发展
小诸葛的博客4 小时前
Apache BookKeeper Ledger 的底层存储机制解析
java
半旧5184 小时前
重构谷粒商城11:node快速入门
java·前端·重构
嘤国大力士5 小时前
C++11&QT复习 (十六)
java·开发语言·c++
菜鸟起航ing5 小时前
【Java面试系列】Spring Boot中自动配置原理与自定义Starter开发实践详解 - 3-5年Java开发必备知识
java·spring boot·面试·自动配置·自定义starter
李白的粉5 小时前
基于springboot+vue的课程管理系统
java·毕业设计·课程设计·源代码·课程管理系统
DDDiccc5 小时前
SpringCloud微服务(一)Eureka+Nacos
java·spring cloud·微服务
橘猫云计算机设计5 小时前
ASP.NET图书馆借阅系统(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·后端·爬虫·小程序·毕业设计·asp.net