Spring是如何实现AOP的

本文介绍了Spring如何实现AOP,首先阐述了AOP的概念,作为面向对象编程的补充,用于处理横切关注点,如日志记录和安全控制。接着,通过配置和源码分析,解释了Spring AOP中的连接点、切入点、通知、切面等概念,并通过一个简单的示例展示了Spring AOP的配置。最后,文章探讨了Spring AOP的源码实现,包括代理模式在其中的作用,以及如何通过bean后置处理器生成AOP代理类。

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


前言

AOP即面向切面编程,是一种编程思想,作为面向对象思想的补充,目的是方便增强方法,处理一些具有横切性质的服务,比如日志记录,安全控制等,强大的Spring框架中亦运用了这种思想,那在探究了Spring实现AOP过程之后,在这里记录下自己的理解;


一、AOP是什么?

    理解AOP之前,我们先回顾一下OOP(面向对象编程),众所周知,OOP的特点是继承、封装、多态,其中封装的一个目的就是把方法与类进行松耦合,在使用的时候,不同的类可以方便的调用各自的功能,说白了就是代码分散,增加代码重用性,降低代码复杂度。但是当代码分散的时候,也带来一个问题,打个比方,假如现在有两个类都要使用同一个日志打印方法,那根据OOP的思想,我需要在两个类中调用这个方法,但是注意这个独立的方法是在一个独立的类中,这样调用类和方法类就有了明显的耦合关系,独立方法类的改变会影响到调用类,那么有什么办法可以随意的加入代码的,那AOP就是做这样的事情,在程序预编译或者动态运行时,把公共操作切入类的指定方方法和指定位置处,这个就是面向切面编程(AOP),用一张图来表示AOP的思想:
三条业务线都要验证用户
    如图所示,前者在不同的业务线中都插入了验证用户的代码,后者是把验证用户的代码,横向的切入到业务中(为了展示切入过程,放大了线条,实质上这种切入是不用修改业务的原来的代码的),Spring框架就具有这种能力,其关键就是运用了代理模式,在之前的文章对代理模式有专门介绍:一文搞懂代理模式

二、个人理解

理解了代理模式之后,对SpringAOP的理解从两个方面入手:

2.1 配置

  本节介绍spring中关于AOP的配置以及涉及的常见AOP相关术语
  1.常见AOP术语

  • JoinPoint(连接点):指的是那些被拦截的点,在spring中这些点就是一个一个的方法。
  • PointCut(切入点):指的是我们定义的想要拦截的点
    注意: 连接点相当于菜单(spring中所有方法都可以是连接点),切入点才是真正的我们想点的菜
  • Advice(通知):通知就是指作用到切入点上的具体方法,分为前置通知(Before)、后置通知(After)、环绕通知(Around)等。
  • Aspect(切面或者方面):切面就是多个切点和通知的集合。
  • Target(目标对象):代理的目标对象(要增强的类)
  • Weaving(织入):把切面应用到目标对象来创建新的代理对象的过程就叫织入。Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
  • Proxy(代理):目标类被增强以后,会生成结果代理类。

  2.Spring中关于AOP的配置
    这里直接上示例:
    创建一个maven类型的spring项目,这里就不赘述了,直接上pom.xml中的依赖引入部分

<dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.18</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.18</version>
        </dependency>
    </dependencies>

    创建一个带有@Aspect注解的方面类,这个就是Spring中关于Aspect的具体表现形式:

@Aspect
//方面类(用 @Aspect 修饰的类)和其他类一样可以
// 有方法、属性定义,还可能包括切入点、增强处理定义。
public class LogAspects {
   
……
}

填充切面类:

@Aspect
//方面类(用 @Aspect 修饰的类)和其他类一样可以
// 有方法、属性定义,还可能包括切入点、增强处理定义。
public class LogAspects {
   
	//连接点就默认为项目中所有方法了
    //设置切点
    @Pointcut("execution(public int com.deee.springaop.MathCalculator.*(..))")
    public void pointCut(){
    }

    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint){
   
        Object[] args = joinPoint.getArgs();
        System.out.println(" "+joinPoint.getSignature().getName()+"运行。。@Before的参数列表是:{"+Arrays.asList(args)+"}")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值