SpringAOP详解

news/2024/11/23 20:48:22/

目录

前言:

相关概念

切点表达式规则

代码演示

SpringAOP实现原理

织入(代理的生成时机)

JDK和CGLIB区别

小结:


前言:

    AOP(Aspect Oriented Programming)是思想(面向切面编程),对某一类事情的统一处理。Spring AOP是思想的具体实现框架。

相关概念

1)切面(类)
    某一方面的具体内容处理就是一个切面。比如用户登录判断就是一个切面(接口对于登录权限的校验)。
2)切点(方法)
    定义拦截规则。比如切面对于哪些接口都需要进行判断。
3)通知(方法的具体实现)
    执行AOP业务(具体需要执行的拦截方法)

  • 前置通知:在目标方法(实际要执行的方法)调用之前执行的通知。
  • 后置通知:在目标方法执行之后的通知。
  • 环绕通知:在目标方法执行前,后都执行的通知。
  • 异常通知:在目标方法抛异常执行的通知。
  • 返回通知:在目标方法返回执行的通知。

4)连接点
    所有可能触发切点的点就是连接点(被这个切面所处理的点)。

切点表达式规则

    切点表达式由切点函数组成,其中execution()是最常用的切点函数,用来匹配方法。

语法:

    execution(<修饰符><返回类型><包.类.方法(参数)><异常>)

    修饰符和异常可以省略(一般异常都是省略)

示例:

    execution(* com.example.demo.controller.UserController.*(..))

    匹配UserController类下的任意方法,参数任意。返回值任意。

注意:

    这种表达式的书写是非常繁琐的,目前有更好的AOP实现,可以更加灵活的配置。

代码演示

设置切面

package com.example.demo.common;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;@Aspect // 切面
@Component // 添加到框架中
public class UserAOP {// 切点(配置拦截规则)// 返回值(任意)  具体类(UserController)  方法名(任意)  参数(任意)@Pointcut("execution(* com.example.demo.controller.UserController.*(..))")public void pointcut(){}// 前置通知@Before("pointcut()")public void doBefore() {System.out.println("执行了前置通知:" + LocalDateTime.now());}// 后置通知@After("pointcut()")public void doAfter() {System.out.println("执行了后置通知:" + LocalDateTime.now());}// 环绕通知@Around("pointcut()")public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("开始执行环绕通知");// 执行连接点中的方法(基点)Object obj = joinPoint.proceed();System.out.println("结束执行环绕通知");return obj;}
}

定义连接点

package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@RequestMapping("/user/hello")public String hello() {System.out.println("执行了hello方法");return "hello";}@RequestMapping("/user/login")public String login() {System.out.println("执行了login方法");return "login";}
}

    当访问/user/hello这个接口,控制台的打印。

注意:

    可以清楚的看到执行目标方法时,前置通知、后置通知和环绕通知的执行时机。

SpringAOP实现原理

    Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截(使用动态代理技术实现方法的调用)。

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

织入(代理的生成时机)

    织入是把切面应用到目标对象并创建新的代理对象的过程,切面在指定的连接点被织入到目标对
象中。
在目标对象的生命周期里有多个点可以进行织入:

1)编译期

    切面在目标类编译时被织入。这种方式需要特殊的编译器。AspectJ的织入编译器就
是以这种方式织入切面的。

2)类加载期

    切面在目标类加载到JVM时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ5的加载时织入(load-time weaving. LTW)就支持以这种方式织入切面。

3)运行期

    切面在应用运行的某⼀时刻被织入。⼀般情况下,在织入切面时,AOP容器会为目标对象动态创建⼀个代理对象。SpringAOP就是以这种方式织入切面的。

JDK和CGLIB区别

    1)JDK 实现(反射方式),要求被代理类必须实现接口,之后是通过 InvocationHandler 及 Proxy,在运行时动态的在内存中生成了代理类对象,该代理对象是通过实现同样的接口实现(类似静态代理接口实现的方式),只是该代理类是在运行期时,动态的织入统一的业务逻辑字节码来完成。可以代理任意类。性能相对较高,生成代理对象速度较快。

    2)CGLIB 实现(字节码加强技术),被代理类可以不实现接口,是通过继承被代理类(生成目标对象的子类),在运行时动态的生成代理类对象(字节码加强技术)。无法代理 final 类和 final 方法。性能相对较低,生成代理对象速度较慢。

注意:

    在 Spring 框架中,即使用了 JDK 动态代理又使用 CGLIB,默认情况下使用的是 JDK 动态代理,但是如果目标对象没有实现接口,则会使用 CGLIB 动态代理。

小结:

    面向切面编程就是统一功能的处理,SpringAOP实现了这种技术。通过动态代理的方式:JDK动态代理通过反射的方式实现,速度快,要求被代理类必须实现接⼝。CGLIB通过实现代理类的子类实现动态代理(字节码加强技术),代理类不能是final修饰。


http://www.ppmy.cn/news/315472.html

相关文章

IDL基础语法

1 创建变量 命名规则&#xff1a;变量名必须以字母开头。它们可以包括其它字母&#xff0c;数字&#xff0c;下划线&#xff0c;美元符号。 以下是创建不同数据类型的方法&#xff0c;我们只需了解即可&#xff0c;知道如何创建整型【16位有符号长整型】和浮点型 PRO learn;创…

007: vue中修改el-select选中颜色不生效的办法

第007个 查看专栏目录: 按照VUE知识点 ------ 按照element UI知识点 echarts&#xff0c;openlayers&#xff0c;cesium&#xff0c;leaflet&#xff0c;mapbox&#xff0c;d3&#xff0c;canvas 免费交流社区 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏…

【SpringBoot笔记31】SpringBoot之配置过滤器Filter的方式、配置拦截器Interceptor的方式

这篇文章,主要介绍SpringBoot之配置过滤器Filter的方式、配置拦截器Interceptor的方式。 目录 一、配置过滤器 1.1、使用@WebFilter注解 (1)创建过滤器 (2)启

诺基亚6210 可用的UCWEB7.0正式版下载

诺基亚6210 可用的UCWEB7.0正式版下载6210上最好的手机浏览器哈完美支持各种网页&#xff0c;支持百度&#xff0c;GG搜索&#xff0c;支持视频播放。。 6210 ucweb 7.0下载地址&#xff1a;http://www.ucwebxz.cn/ucweb-60V3.SISX下载后把SISX文件复制到手机内存卡上&#xff…

什么是 JWT?

起源 需要了解一门技术&#xff0c;首先从为什么产生开始说起是最好的。JWT主要用于用户登录鉴权&#xff0c;所以我们从最传统的session认证开始说起。 session认证 众所周知&#xff0c;http协议本身是无状态的协议&#xff0c;那就意味着当有用户向系统使用账户名称和密码进…

接口参数加密+时效性检验+签名

一个API就是一把开启神圣之门的钥匙. 只有我的子民才能拿着它, 进入我的王国中. API裸奔,接口暴露, 大门敞开,任何人都可以进入… 接口参数加上公钥,是我发给子民的一把钥匙 . 当一个小偷, 在某个夜黑风高的晚上拿走了这把钥匙, 它也能瞥见我王国的一面. 然后我会在接口参数中…

JWT教程

JWT教程 官方地址&#xff1a;https://jwt.io What is JSON Web Token? JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information c…

Android中接入腾讯TBS浏览器WebView的入坑指南

为什么不使用原生的webview&#xff1f; 最近公司的项目接入了webview&#xff0c;但是坑巨多无比&#xff0c;尤其是其内存泄露。所以我在想是否可以有第三方封装了webview。 比较Crosswalk与TBS服务 1.Crosswalk这玩意儿我没用过&#xff0c;据说是很流畅和强大&#xff0…