1. 什么是 Spring AOP

AOP (Aspect Oriented Programming): 面向切面编程, 它是一种思想, 它是对某一类事情的集中处理.

例如, 在没有学习AOP之前, 之前的判断当前登录状态, 就需要在每一个页面都实现登录校验, 在有了AOP之后, 外面只需在某一处配置以下, 所有的页面就都可以实现登录验证了, 就不需要写太多重复的代码,

Spring AOP, 是一个框架, 提高了一种对 AOP 思想的实现.

2. AOP 的组成

2.1 切面 (Aspect)

切面由切点和通知组成, 它既包含了横切逻辑的定义, 也包括了连接点的定义.

切面是包含了: 通知, 切点和切面的类, 相当于 AOP 实现的某个功能的集合

2.2 切点 (Pointcur)

切点的作用就是提供一组规则 (使用 AspectJ pointcut expression language 来描述) 来匹配 连接点, 给满足规则的 连接点添加 Advice

切点相当于保存了众多连接点的一个集合

2.3 连接点 (Join Point)

应用执行过程中能够插入切面的一个点, 这个点可以是方法的调用时, 抛出异常时, 甚至修改字段时. 切面代码可以利用这些点插入到应用的正常流程之中, 并添加新的行为.

连接点相当于需要被增强的某个 AOP 功能的所有方法.

2.4 通知 (Advice)

定义了切面是什么, 何时使用, 其描述切面要完成的工作, 还解决何时执行这个工作的问题,

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

⽅法进⾏调用:

前置通知使用 @Before:通知方法会在目标方法调用之前执行.

后置通知使用 @After:通知方法会在目标方法返回或者抛出异常后调用.

返回之后通知使用 @AfterReturning:通知方法会在目标方法返回后调用.

抛异常后通知使用 @AfterThrowing:通知方法会在目标方法抛出异常后调用.

环绕通知使用 @Around:通知包裹了被通知的方法, 在被通知的方法通知之前和调用之后执行自定义的行为.

3. Spring AOP 的使用

3.1 添加 AOP 框架

在 pom.xml 中添加依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/springboot-starter-aop -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

3.2 定义切面和切点

@Aspect // 定义切面
@Component
public class UserAspect {
    // 切点 (配置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*)")
    public void pointcut() {
        // 这是一个空方法, 不需要有具体的实现
    }
}

切点表达式注意事项

AspectJ 支持三种通配符

  • * : 匹配任意字符, 只匹配一个元素 (包, 类, 方法, 方法参数)
  • .. : 匹配任意字符,可以匹配多个元素, 在标识类时, 必须联合 * 使用
  • : 表示按类型匹配指定类和所有类, 必须跟在类名后面, 如 com.cad.Car , 表示继承该类的所有子类包括本身

execution() 是最常用的切点函数

语法为: execution(<修饰符> <返回类型> <包.类.方法(参数)> <异常>) (注意: 修饰符和异常可以省略)

示例:

  • execution(* com.cad.demo.User.*(..)) :匹配 User 类⾥的所有⽅法。
  • execution(* com.cad.demo.User .*(..)) :匹配该类的⼦类包括该类的所有⽅法。
  • execution(* com.cad.*.*(..)) :匹配 com.cad 包下的所有类的所有⽅法。
  • execution(* com.cad..*.*(..)) :匹配 com.cad 包下、⼦孙包下所有类的所有⽅法。
  • execution(* addUser(String, int)) :匹配 addUser ⽅法,且第⼀个参数类型是 String,第⼆个参数类型是 int。

3.3 定义通知 (五种)

@Aspect // 定义切面
@Component
public class UserAspect {
    // 切点 (配置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
        // 这是一个空方法, 不需要有具体的实现
    }
    @Before("pointcut()")
    public void doBefore(){
        System.out.println("执行 Before 方法");
    }
    @After("pointcut()")
    public void doAfter(){
        System.out.println("执行 After 方法");
    }
    @AfterReturning("pointcut()")
    public void doAfterReturning() {
        System.out.println("执行 AfterReturning 方法");
    }
    @AfterThrowing("pointcut()")
    public void doAfterThrowing() {
        System.out.println("执行 AfterThrowing 方法");
    }
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object object = null;
        System.out.println("Around 方法开始执行");
        try {
            // 执行拦截方法
            object = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("Around 方法结束执行");
        return object;
    }
}

正常时

抛出异常时

4. Spring AOP 实现原理

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

Spring AOP 是基于动态代理实现的.

动态代理分为两类:

  • JDK Proxy(JDK 动态代理机制)
  • CGLIB 动态代理

默认情况下, 实现了接口的类, 使用 AOP 会基于 JDK 生成代理类, 没有实现接口的类, 会基于 CGLIB 生成代理类

4.1 织入 (Weaving)

代理的生成时机

织⼊是把切面应用到目标对象并创建新的代理对象的过程,切面在指定的连接点被织⼊到目标对象中。

在目标对象的⽣命周期里有多个点可以进⾏织入:

  • 编译期:切面在目标类编译时被织⼊。这种⽅式需要特殊的编译器。AspectJ的织⼊编译器就是以这种方式织入切⾯的。
  • 类加载器:切⾯在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入(load-time weaving. LTW)就支持以这种方式织入切面。
  • 运行期:切面在应用运行的某⼀时刻被织入。⼀般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象. Spring AOP 就是以这种方式织入切面的

4.2 JDK 和 CGLIB 实现的区别

  • JDK 实现要求被代理类必须实现接口, 之后是通过 InvocationHandlerProxy, 在运行时动态的在内存中生成了代理类对象, 该代理对象是通过实现同样的接口实现 (类似静态代理接口实现的方式), 只是该代理类是在运行期时,动态的织入统一的业务逻辑字节码来完成.
  • CGLIB 实现, 被代理类可以不实现接口, 是通过继承被代理类, 在运行时动态的生成代理类对象.

到此这篇关于Spring AOP详解面向切面编程思想的文章就介绍到这了,更多相关Spring AOP切面编程内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Spring AOP详解面向切面编程思想的更多相关文章

  1. Spring JdbcTemplate执行数据库操作详解

    JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下

  2. Spring Batch批处理框架操作指南

    Spring Batch 是 Spring 提供的一个数据处理框架。企业域中的许多应用程序需要批量处理才能在关键任务环境中执行业务操作,这篇文章主要介绍了Spring Batch批处理框架操作指南,需要的朋友可以参考下

  3. Spring详细讲解@Autowired注解

    @Autowired注解可以用在类属性,构造函数,setter方法和函数参数上,该注解可以准确地控制bean在何处如何自动装配的过程。在默认情况下,该注解是类型驱动的注入

  4. 使用Spring AOP实现用户操作日志功能

    这篇文章主要介绍了使用Spring AOP实现了用户操作日志功能,功能实现需要一张记录日志的log表,结合示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. Spring Security认证器实现过程详解

    一些权限框架一般都包含认证器和决策器,前者处理登陆验证,后者处理访问资源的控制,这篇文章主要介绍了Spring Security认证器实现过程,需要的朋友可以参考下

  6. 解析SpringBoot中使用LoadTimeWeaving技术实现AOP功能

    这篇文章主要介绍了SpringBoot中使用LoadTimeWeaving技术实现AOP功能,AOP面向切面编程,通过为目标类织入切面的方式,实现对目标类功能的增强,本文给大家介绍的非常详细,需要的朋友可以参考下

  7. spring学习JdbcTemplate数据库事务管理

    这篇文章主要为大家介绍了spring学习JdbcTemplate数据库事务管理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  8. Spring Boot 集成Redisson实现分布式锁详细案例

    这篇文章主要介绍了Spring Boot 集成Redisson实现分布式锁详细案例,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下

  9. 如何利用Java使用AOP实现数据字典转换

    这篇文章主要介绍了如何利用Java使用AOP实现数据字典转换,AOP也是我们常说的面向切面编程,AOP在我们开发过程中应用也比较多,在这里我们就基于AOP来实现一个数据字典转换的案例

  10. Spring Security实现接口放通的方法详解

    在用Spring Security项目开发中,有时候需要放通某一个接口时,我们需要在配置中把接口地址配置上,这样做有时候显得麻烦。本文将通过一个注解的方式快速实现接口放通,感兴趣的可以了解一下

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部