• 面向切面AOP


    AOP思想实际上就是:在运行时,动态地将代码切入到类的指定方法、指定位置上.也就是说,我们可以使用AOP来帮助我们在方法执行前或执行之后,做一些额外的操作,实际上,就是代理!

    通过AOP我们可以在保证原有业务不变的情况下,添加额外的动作。比如我们的某些方法执行完成之后,需要打印日志,那么这个时候,我们就可以使用AOP来帮助我们完成,它可以批量地为这些方法添加动作。可以说,它相当于将我们原有的方法,在不改变源代码的基础上进行了增强处理。

    相当于我们的整个业务流程,被直接斩断,并在断掉的位置添加了一个额外的操作,再连接起来,也就是在一个切点位置插入内容。它的原理实际上就是通过动态代理机制实现的,Spring底层并不是使用的JDK提供的动态代理,而是使用的第三方库实现,它能够以父类的形式代理,而不是接口。

    使用SpringAOP

    先导入一个依赖

    1. <dependency>
    2. <groupId>org.springframeworkgroupId>
    3. <artifactId>spring-aspectsartifactId>
    4. <version>5.3.13version>
    5. dependency>

    明确实现AOP操作需要知道这些内容

    1. 需要切入的类,类的哪个方法需要被切入

    2. 切入之后需要执行什么动作

    3. 是在方法执行前切入还是在方法执行后切入

    4. 如何告诉Spring需要进行切入

    找到需要切入的类

    1. public class Student {
    2. String name;
    3. int age;
    4. //分别在test方法执行前后切入
    5. public int test(String str) {
    6. System.out.println("我是一个测试方法:"+str);
    7. return str.length();
    8. }
    9. }

    定义方法执行前后我们要执行的操作

    1. public class AopTest {
    2. //执行之后的方法
    3. public void after(){
    4. System.out.println("我是执行之后");
    5. }
    6. //执行之前的方法
    7. public void before(){
    8. System.out.println("我是执行之前");
    9. }
    10. }

    @Before

    前置通知:目标方法之前执行

    @After

    后置通知:目标方法之后执行(始终执行)

    @AfterReturning

    返回通知:执行方法结束前执行(异常不执行)

    @AfterThrowing

    异常通知:出现异常的时候执行

    @Around

    环绕通知:环绕目标方法执行

    将要进行AOP操作的类注册为Bean

    1. <bean name="student" class="com.test.bean.Student"/>
    2. <bean name="aopTest" class="com.test.aop.AopTest"/>

    一个是Student类,还有一个就是包含我们要切入方法的AopTest类,注册为Bean后,他们就交给Spring进行管理,这样Spring才能帮助我们完成AOP操作

    修改顶部,引入aop相关标签

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:aop="http://www.springframework.org/schema/aop"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    6. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    使用`aop:config`来添加一个新的AOP配置

       

    告诉Spring,我们要切入的是哪一个类的哪个或是哪些方法

    pointcut id="test" expression="execution(* com.test.bean.Student.test(String))"/>

    `expression`属性的`execution`填写格式如下

    修饰符 包名.类名.方法名称(方法参数)

    * 修饰符:public、protected、private、包括返回值类型、static等等(使用*代表任意修饰符)

    * 包名:如com.test(*代表全部,比如com.*代表com包下的全部包)

    * 类名:使用*也可以代表包下的所有类

    * 方法名称:可以使用*代表全部方法

    * 方法参数:填写对应的参数即可,比如(String, String),也可以使用*来代表任意一个参数,使用..代表所有参数。

    也可以使用其他属性来进行匹配,比如`@annotation`可以用于表示标记了哪些注解的方法被切入

    为此方法添加一个执行前动作和一个执行后动作

    1. <aop:aspect ref="aopTest">
    2. <aop:before method="before" pointcut-ref="test"/>
    3. <aop:after-returning method="after" pointcut-ref="test"/>
    4. aop:aspect>

    配置完成

    1. public static void main(String[] args) {
    2. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
    3. Student student = context.getBean(Student.class);
    4. student.test("lbwnb");
    5. }

    方法执行前后,分别调用了我们对应的方法。但是仅仅这样还是不能满足一些需求,在某些情况下,我们可以需求方法执行的一些参数,比如方法执行之后返回了什么,或是方法开始之前传入了什么参数等等。

    这个时候,我们可以为我们切入的方法添加一个参数,通过此参数就可以快速获取切点位置的一些信息

    1. //执行之前的方法
    2. public void before(JoinPoint point){
    3. System.out.println("我是执行之前");
    4. System.out.println(point.getTarget()); //获取执行方法的对象
    5. System.out.println(Arrays.toString(point.getArgs())); //获取传入方法的实参
    6. }

    通过添加JoinPoint作为形参,Spring会自动给我们一个实现类对象,这样我们就能获取方法的一些信息了。

    环绕方法相当于完全代理了此方法,它完全将此方法包含在中间,需要我们手动调用才可以执行此方法,并且我们可以直接获取更多的参数

    编写实现环绕的方法,通过`proceed`方法来执行代理的方法

    1. public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    2. System.out.println("方法开始之前");
    3. Object value = joinPoint.proceed();
    4. System.out.println("方法执行完成,结果为:"+value);
    5. return value;
    6. }

    修改xml

    
        
        
    

    使用接口实现AOP

    首先我们需要将一个类实现Advice接口,只有实现此接口,才可以被通知,比如我们这里使用`MethodBeforeAdvice`表示是一个在方法执行之前的动作

    1. public class AopTest implements MethodBeforeAdvice {
    2. @Override
    3. public void before(Method method, Object[] args, Object target) throws Throwable {
    4. System.out.println("通过Advice实现AOP");
    5. }
    6. }

    args代表的是方法执行前得到的实参列表,还有target表示执行此方法的实例对象

    修改xml

       

       

    `AfterReturningAdvice`就需要实现一个方法执行之后的操作

    1. public class AopTest implements MethodBeforeAdvice, AfterReturningAdvice {
    2. @Override
    3. public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    4. System.out.println("我是方法执行之后!");
    5. }
    6. }

    AOP 领域中的特性术语

    - 通知(Advice): AOP 框架中的增强处理,通知描述了切面何时执行以及如何执行增强处理,也就是我们上面编写的方法实现。

    - 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出,实际上就是我们在方法执行前或是执行后需要做的内容。

    - 切点(PointCut): 可以插入增强处理的连接点,可以是方法执行之前也可以方法执行之后,还可以是抛出异常之类的。

    - 切面(Aspect): 切面是通知和切点的结合,我们之前在xml中定义的就是切面,包括很多信息。

    - 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。

    - 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,我们之前都是在将我们的增强处理添加到目标对象,也就是织入

  • 相关阅读:
    3d渲染农场全面升级,好用的渲染平台值得了解
    Spring-Security前后端分离权限认证
    网络协议常用面试题汇总(二)
    uni-app:实现页面效果2(canvas绘制,根据页面宽度调整元素位置)
    学生党双11有哪些值得入手的蓝牙耳机?适合学生党的蓝牙耳机推荐
    Redis持久化、主从与哨兵架构详解
    知识表示学习(三):TransR
    什么是RESTful API,Spring MVC如何支持RESTful架构
    使用echarts绘制3DChart图表
    详解js数组操作——filter()方法
  • 原文地址:https://blog.csdn.net/weixin_51992178/article/details/126914277