浅识Spring AOP

简介: 浅识Spring AOP

Spring AOP


引言(just I think): 因为java是面向对象编程,而面向对象是纵向继承机制,无法集中注意力到核心代码中,所以我们需要调用其他的机制来解决非核心代码的包装,将其从核心代码块中解耦出来


首先我们从spring官网了解一下他们对AOP思想的介绍


官网地址:docs.spring.io/spring-fram…


面向方面编程 (AOP) 通过提供另一种思考程序结构的方式来补充面向对象编程 (OOP)。OOP 中模块化的关键单元是类,而在 AOP 中,模块化的单元是方面 。方面使关注点模块化,例如跨越多种类型和对象的事务管理。(此类关注点在 AOP 文献中通常称为横切关注点。)


Spring 的关键组件之一是AOP 框架。虽然 Spring IoC 容器不依赖于 AOP,这意味着您不需要使用 AOP,但 AOP 补充了 Spring IoC 以提供非常强大的中间件解决方案。


具体概念


***AOP(Aspect Oriented Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面 向对象编程的一种补充和完善,它以通过预编译方式和运行期动态代理方式实现在不修改源代码的情况 下给程序动态统一添加额外功能的一种技术  。***


AOP的相关相关术语:


横切关注点


就是从每个核心方法中抽取出来的非核心代码(既非核心业务逻辑),最后放入一个类中(这个类叫切面),不同的业务逻辑实现不同的方法


这个概念不是语法层面天然存在的,而是根据附加功能(核心方法中的非核心代码)的逻辑上的需要:有十个附加功能(核心方法中的非核心代码),就有十个横切关注点。

 

通知


简单地说就是在切面中,非核心业务也就是我们需要做的事,被封装成为一个方法(该方法叫通知)—-通知就是横切关注点的实现。


1.切面

封装横切关注点或者说是通知的类


1.目标

被代理的目标对象


1.代理

向目标对象应用通知之后创建的代理对象(不需要我们自己创建,封装的就是)AOP帮助我们创建


1.连接点

这也是一个纯逻辑概念,不是语法定义的。 把方法排成一排,每一个横切位置看成x轴方向,把方法从上到下执行的顺序看成y轴,x轴和y轴的交叉 点就是连接点


从哪里套出来的就放回哪里,不改变元代码的逻辑


1.切入点

定位连接点的方式(位置)。


作用

  • 简化代码: 把方法中固定位置的重复的代码抽取出来,让被抽取的方法更专注于自己的核心功能, 提高内聚性。
  • 代码增强: 把特定的功能封装到切面类中,看哪里有需要,就往上套,被套用了切面逻辑的方法就 被切面给增强了。


基于注解的AOP


技术说明:


几种动态代理


  • 动态代理(InvocationHandler):JDK原生的实现方式,需要被代理的目标类必须实现接口。因 为这个技术要求代理对象和目标对象实现同样的接口(兄弟两个拜把子模式)。
  • cglib:通过继承被代理的目标类(认干爹模式)实现代理,所以不需要目标类实现接口。
  • AspectJ:本质上是静态代理,将代理逻辑“织入”被代理的目标类编译得到的字节码文件,所以最 终效果是动态的。weaver就是织入器。Spring只是借用了AspectJ中的注解。


通过阅读官方文档我们可以知道 :


Spring AOP 默认使用标准的 J2SE* 动态代理* 作为 AOP 代理。这使得任何接口(或接口集)都可以被代理。


启用AOP顺序


  1. 将目标对象和切面交给IOC容器管理(注解+扫描)
  2. 将切面类和目标类作为容器中的组件,所以加@Component
  3. 将当前组件用@Aspect注解标注为切面
  4. 开启基于注解的aop ( 开启AspectJ的自动代理,为目标对象自动生成代理 )

<!--    作用: 开启基于注解的aop-->
    <aop:aspectj-autoproxy/>

1.配置好切入点表达式 :

声明一个方法,然后使用@Poincut注解来进行声明公共的切入点表达式 可)


/**
     * 切入点表达式的重用******重点
     */
//    execution(权限修饰符 返回值 项目. 包/ *  . 类/ * .方法 (..) )
    @Pointcut("execution(* com_Ray.such.*.*(..))")
    public void pointCut(){}


AOP的各种通知详解


各种通知的执行顺序:


Spring版本5.3.x以前:

前置通知 -->目标操作--> 后置通知--> 返回通知 / 异常通知

Spring版本5.3.x以后:

前置通知--> 目标操作--> 返回通知 / 异常通知--> 后置通知


1.前置语法:

使用@Before注解标识,在被代理的目标方法前执行


@Before("pointCut()")
    public void beforeAdviceMethod(JoinPoint joinPoint){
        //1. 获取连接点所对应方法的方法名
        Signature signature = joinPoint.getSignature();
        //2.  获取连接点所对应方法的参数
        Object[] args = joinPoint.getArgs();
        System.out.println("方法名为: " + signature.getName()+ ",参数为: " + Arrays.toString(args));
//        System.out.println("前置通知!");
    }
joinPoint 作为前置通知的方法的参数 ,可以获取连接点多对应的方法的签名信息()


1.后置语法

注解 :@After(“point Cut()”)在方法执行之后的finally中执行


返回通知

注解: @AfterReturn(“point Cut()“) 在目标对象执行之后执行

/**
 * 返回通知!
 * 在目标方法返回值之后的一个通知
 */
@AfterReturning("pointCut()")
public void afterReturn(JoinPoint joinPoint){
    Signature signature = joinPoint.getSignature();
    System.out.println("方法: " + signature.getName()+"执行返回通知");
}


1.异常通知

/**
 * 异常通知
 */
@AfterThrowing(value = "pointCut()",throwing = "ex")
public void AfterThrow(JoinPoint joinPoint, Throwable ex){
    Signature signature = joinPoint.getSignature();
    System.out.println("方法: " + signature.getName()+"的异常通知:" + ex);
}


1.环绕通知---@Around( )

设置环绕通知之后就可以将所有前面的通知都涵盖进去


基于XML的AOP



其基本与基于注解实现一样


配置xml环境


<context:component-scan base-package="com.atguigu.aop.xml"></context:componentscan>
<aop:config>
<!--配置切面类-->
<aop:aspect ref="loggerAspect">
    <aop:pointcut id="pointCut" expression="execution(*
com.atguigu.aop.xml.CalculatorImpl.*(..))"/>
    <aop:before method="beforeMethod" pointcut-ref="pointCut"></aop:before>
    <aop:after method="afterMethod" pointcut-ref="pointCut"></aop:after>
    <aop:after-returning method="afterReturningMethod" returning="result"
                         pointcut-ref="pointCut"></aop:after-returning>
    <aop:after-throwing method="afterThrowingMethod" throwing="ex" pointcutref="pointCut"></aop:after-throwing>
    <aop:around method="aroundMethod" pointcut-ref="pointCut"></aop:around>
</aop:aspect>
<aop:aspect ref="validateAspect" order="1">
    <aop:before method="validateBeforeMethod" pointcut-ref="pointCut">
    </aop:before>
</aop:aspect>
</aop:config>


目录
相关文章
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
940 0
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
1783 13
|
XML Java 开发者
Spring Boot中的AOP实现
Spring AOP(面向切面编程)允许开发者在不修改原有业务逻辑的情况下增强功能,基于代理模式拦截和增强方法调用。Spring Boot通过集成Spring AOP和AspectJ简化了AOP的使用,只需添加依赖并定义切面类。关键概念包括切面、通知和切点。切面类使用`@Aspect`和`@Component`注解标注,通知定义切面行为,切点定义应用位置。Spring Boot自动检测并创建代理对象,支持JDK动态代理和CGLIB代理。通过源码分析可深入了解其实现细节,优化应用功能。
844 6
|
11月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
1562 0
|
XML Java 测试技术
Spring AOP—通知类型 和 切入点表达式 万字详解(通俗易懂)
Spring 第五节 AOP——切入点表达式 万字详解!
1328 25
|
XML 安全 Java
Spring AOP—深入动态代理 万字详解(通俗易懂)
Spring 第四节 AOP——动态代理 万字详解!
688 24
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
673 2
Spring Aop该如何使用