Spring AOP统一功能处理

简介: 这篇文章主要介绍AOP(Aspect Oriented Programming)——面向切面编程的思想,它是对某一类事情的集中处理,也是对OOP(Object Oriented Programming)面向对象编程的补充和完善。

1.面向切面编程AOP


1.1 什么是AOP?


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


AOP是一种思想,而Spring AOP这个框架是对AOP思想的实现,它们的关系和IoC和DI类似。


1.2 AOP的作用


想象一个场景,我们在做后台系统时,除了登录和注册等几个功能不需要做用户登录验证之外,其他几乎所有页面调用的前端控制器(Controller)都需要先验证用户登录的状态,那么这个时候我们要怎么处理呢?


如果不使用AOP,我们之前的处理方式是每个Controller都要写一遍用户登录验证,然而当你的功能越来越多,那么你要写的登录验证也越来越多,就有了很多重复的代码,而且这些方法的代码修改和维护的成本就会很高。


如果使用AOP,在进入业务代码之前进行统一的一个处理,去验证用户是否登录。


除了统一的用户登录判断之外,AOP还可以实现:


  • 统一日志记录
  • 统一方法执行时间统计
  • 统一的返回格式设置
  • 统一的异常处理
  • 事务的开启和提交


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


1.3 AOP基础组成


AOP由以下四部分组成:


1.切面(Aspect):定义AOP业务类型(表示当前AOP是做什么的)。

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

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

4.通知(Advice)【增强方法】:定义什么时候干什么事。

a) 前置通知:在拦截的目标方法之前执行的通知(事件)

b)后置通知:在拦截的目标方法之后执行的通知(事件)

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

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

e)环绕通知:在拦截方法执行前后都执行的通知。


AOP整个组成部分的概念如下图所示,以多个页面都要访问用户登录权限为例:


微信图片_20230111221937.png

2.Spring AOP 实现


我们接下来使用Spring AOP来实现AOP的功能,完成的目标是拦截所有UserController里面的方法,每次调用UserController中任意一个方法时,都执行相应的通知事件。


Spring AOP的具体实现步骤如下:


2.1添加 Spring AOP 框架支持


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

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


2.2定义切面和切点


切点指的是具体要处理的某一类问题,比如用户登录权限验证就是一个具体的问题,记录所有方法的执行日志就是一个具体的问题,切点定义的是某一类问题。


具体实现如下:

微信图片_20230111221933.png

其中pointcut方法为空方法,其不需要方法体,此方法名就是起到一个“标识”的作用,标识下面的通知方法具体指的是哪个切点。


切点表达式说明

AspectJ支持三种通配符

*:匹配任意字符,只匹配一个元素(包,类,或方法,方法参数)

..:匹配任意字符,可以匹配多个元素,在表示类时,必须和*联合使用

+:表示按照类型匹配指定类的所有类,必须跟在类名后面,如com.cad.Car+,表示继承该类的所有子类包括本身


表达式示例如下:


execution(* com.example.demo.UserController. *(..)):匹配UserController类里的所有方法。

execution(* com.example.demo.UserController+.*(..)):匹配UserController类的子类包括该类的所有方法

execution(* com.example.demo.*.*(..)):匹配com.example.demo包下的所有类的所有方法

execution(* com.example.demo..*.*(..)):匹配com.example.demo包下、子孙包下所有类的所有方法

execution(* addUser(String,int)):匹配addUser方法,且第一个参数类型是String,第二个参数类型是int


2.3定义通知


通知定义的是被拦截的方法具体要执行的业务,比如用户登录权限验证方法就是具体要执行的业务。

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

a) 前置通知使用@Before:在拦截的目标方法之前执行的通知(事件)

b)后置通知使用@After:在拦截的目标方法之后执行的通知(事件)

c)返回之后通知使用@AfterReturning:在拦截的目标方法返回数据之后通知

d)抛出异常之后的通知使用@AfterThrowing:在拦截的目标方法抛出异常之后执行的通知

e)环绕通知使用@Around:在拦截方法执行前后都执行的通知。


具体实现如下:


@Component
@Aspect  // 标识当前类为一个切面
public class LoginAop {
    // 定义切点(拦截的规则),使用AspectJ表达式语法
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
    }
    // 前置通知
    @Before("pointcut()")
    public void doBefore() {
        System.out.println("执行了前置通知");
    }
    // 后置通知
    @After("pointcut()")
    public void doAfter() {
        System.out.println("执行了后置通知");
    }
    // 环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object result=null;
        // 前置业务代码
        System.out.println("环绕通知的前置执行方法");
        try {
            // 执行目标方法
            result=joinPoint.proceed();
        }catch (Throwable e) {
            e.printStackTrace();
        }
        // 后置业务执行代码
        System.out.println("环绕通知的后置执行代码");
        return result;
    }
}


访问UserController类中方法对应的URL,控制台打印结果如下图:


微信图片_20230111221924.png

3.Spring AOP 实现原理


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


Spring AOP支持 JDK Proxy 和 CGLIB 方式实现动态代理。默认情况下,实现了接口的类,使用AOP会基于JDK生成代理类,没有实现接口的类,会基于 CGLIB 生成代理类。


微信图片_20230111221916.png


Spring AOP本质就是生成了一个目标对象的代理类,当前端传来请求时,不会将请求直接交给目标对象,而是首先由代理类进行处理,如果满足一定的条件,才会将请求交给目标对象。


比如:如果处理请求前需要登录验证,那么代理类会去验证用户是否登录,如果用户登录了才会将请求交给目标对象并执行核心业务代码,否则代理类将返回响应让用户先登录。


4.总结

AOP是对某方面能力的统一实现,它是一种实现思想,Spring AOP是对AOP的具体实现,Spring AOP可通过AspectJ(注解)的方式来实现AOP的功能,Spring AOP的实现步骤是:


1.添加AOP框架支持

2.定义切面和切点

3.定义通知


Spring AOP是通过动态代理的方式,在运行期将AOP代码织入到程序中的,它的实现方式有两种:JDK Proxy和CGLIB。


相关文章
|
4天前
|
消息中间件 缓存 Java
手写模拟Spring Boot启动过程功能
【11月更文挑战第19天】Spring Boot自推出以来,因其简化了Spring应用的初始搭建和开发过程,迅速成为Java企业级应用开发的首选框架之一。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,帮助读者深入理解其工作机制。
21 3
|
4天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
19 0
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
42 4
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
143 1
|
28天前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
35 0
|
17天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
95 62
|
8天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
28天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
35 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
1月前
|
XML Java 数据格式
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
本文介绍了如何使用Spring框架的注解方式实现AOP(面向切面编程)。当目标对象没有实现接口时,Spring会自动采用CGLIB库进行动态代理。文中详细解释了常用的AOP注解,如`@Aspect`、`@Pointcut`、`@Before`等,并提供了完整的示例代码,包括业务逻辑类`User`、配置类`SpringConfiguration`、切面类`LoggingAspect`以及测试类`TestAnnotationConfig`。通过这些示例,展示了如何在方法执行前后添加日志记录等切面逻辑。
85 2
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
|
13天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1