Spring AOP

本文介绍了AOP基本概念,它是OOP的补充,可分离核心与横切关注点。阐述了AOP术语,如通知、连接点等。还讲解了Spring AOP的使用,包括添加jar包、命名空间等,其优点有降低耦合度等。最后给出了Spring4和Spring5中AOP通知的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP基本概念

概念:

  • AOP是 Aspect Oriented Programing 的简称,中文最初翻译为"面向方面编程",通常我们更喜欢称之为"面向切面编程"。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能,日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其它类型的代码,如安全性、异常处理也是如此。这种散布在各处的代码被称为横切(cross cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用,因此引入了AOP的编程理念,可以说AOP是OOP的补充和完善。
  • AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,它们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

AOP术语

AOP

通知----Advice

  • 切面也是有目标的 ——它必须完成的工作。在AOP术语中,切面的工作被称之为通知。
  • 通知:定义了切面是什么,何时使用,其描述了切面要完成的工作,还解决何时执行这个工作的问题。
  • Spring切面可以应用5种类型的通知:
  • 前置通知(Before): 在目标方法被调用之前调用通知功能;
  • 后置通知(After): 在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
  • 返回通知(After-returning):在目标方法成功执行之后调用通知;
  • 异常通知(After-throwing): 在目标方法抛出异常后通知调用;
  • 环绕通知(Around):通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为。

连接点----Join Point

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

切点----Pointcut

  • 切点:是缩小切面所通知的连接点的范围。如果说通知定义了切面是什么和何时的话,那么切点就定义了何处。切点的定义会匹配通知所要织入的一个或者多个连接点。我们通常会使用明确的类和方法名称,或者利用正则表达式定义所匹配的类和方法名来指定这些切点。

切面----Aspect

  • 切面:是通知和切点的结合。通知和切点共同定义了切面的全部内容————它是什么,在何时,在何处完成其功能。

织入----weaving

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

编译期:

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

类加载器:

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

运行期:

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

Spring AOP

  • 添加需要的jar包

在这里插入图片描述

  • 添加命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  • 添加xml
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • 代码
package com.github.Factory;

interface ISubject{
  void eat();
}
package com.github.Factory;

class RealSubject implements ISubject{
   @Override
   public void eat() {
       System.out.println("我要吃1个苹果");
   }
}
package com.github.Factory;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
class ProxySubject {

   @Pointcut("execution(* eat*(..))")
   private void ProxyInstance(){}

   @Before("ProxyInstance()")
   public void preHandle(){
       System.out.println("-------------before---------");
   }

  @After("ProxyInstance()")
   public void aftHandle(){
       System.out.println("-------------After-----------");
   }
   
}
package com.github.Factory;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Client {
   public static void main(String[] args) {
       ApplicationContext context = new  ClassPathXmlApplicationContext("applicationContext.xml");
       ISubject iSubject = (ISubject) context.getBean("realsubject");
       iSubject.eat();
   }
}

优点:

  • 降低模块耦合度
  • 使系统容易扩展
  • 延迟设计决定:使用AOP,设计师可以推迟为将来的需求作决定,因为需求作为独立的方面很容易实现
  • 更好的代码复用性

2021-10-10 补充

AOP的通知执行顺序

1.Spring4执行顺序

  • 正常顺序
  1. 前置环绕通知
  2. 前置通知
  3. 业务逻辑
  4. 后置环绕通知
  5. 后置通知
  6. 返回通知
  • 异常顺序
  1. 前置环绕通知
  2. 前置通知
  3. 业务逻辑
  4. 后置通知
  5. 异常通知

2.Spring5执行顺序

  • 正常顺序
  1. 前置环绕通知
  2. 前置通知
  3. 业务逻辑
  4. 返回通知
  5. 后置通知
  6. 后置环绕通知
  • 异常顺序
  1. 前置环绕通知
  2. 前置通知
  3. 业务逻辑
  4. 异常通知
  5. 后置通知
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值