Spring动态代理与AOP

news2024/12/26 11:35:21

AOP中的@Before是如何实现的?

在AOP(面向切面编程)中,@Before注解通常用于定义一个在方法执行前执行的前置通知(advice)。在Spring框架中,实现@Before功能的底层机制主要基于代理(Proxy)技术,这里的代理可以是JDK动态代理或者CGLIB代理,具体取决于你的配置或API使用情况。

以下是在Spring中使用@Before注解的@Before通知是如何实现的:

1. 配置方式

首先,你需要在Spring配置文件中或者使用@EnableAspectJAutoProxy注解来启用AOP支持。

例如,在XML配置中:

<aop:aspectj-autoproxy />

或使用Java配置:

@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}

2. Aspect定义

在Spring中,使用@Aspect注解来定义一个切面(Aspect),在切面中你可以定义多个通知(advice),包括@Before通知。

@Aspect
public class LoggingAspect {
    @Before("execution(* com.example.exampleClass.*(..))")
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("Method " + joinPoint.getSignature().getName() + " is called");
    }
}

3. 代理实现

当Spring识别到@Before通知后,它会创建一个代理对象,这个代理对象在调用目标方法之前会执行beforeAdvice方法。代理对象实际上是一个动态生成的类,它会通过JDK动态代理或CGLIB来创建。

  • JDK动态代理:如果目标方法的类使用了接口,并且Spring配置文件中启用了JDK代理,那么使用JDK动态代理创建代理对象。
  • CGLIB代理:如果目标方法的类不是接口或者Spring配置文件中启用了CGLIB代理,那么使用CGLIB创建代理对象。CGLIB库允许你动态地为一个类创建子类。

4. 调用执行

当你调用目标方法时,实际上是在调用代理对象的方法(前提是对象已被Spring容器进行管理。类似地,@Transactional 注解的作用是将一个方法声明为一个事务边界,其目的是确保方法周围的业务逻辑在进行数据库操作时能正确地进行事务管理。在Spring框架中,通常情况下,@Transactional注解需要在@Service注解的类或者方法上使用,这样Spring BootSpring MVC框架才能正确地识别出这是一个服务层的组件,并在需要的地方创建和管理代理对象,从而确保该方法所在的事务被正确地管理)。代理对象在调用方法之前会执行@Before通知中的方法,然后继续调用目标方法的实际逻辑。

总结

通过上述步骤,Spring能够通过动态代理技术,在目标方法执行之前自动调用@Before通知中的方法,实现程序的模块化、可维护性和可扩展性。这样的机制使得开发者能够专注于核心业务逻辑,而不需要在每一处方法调用中编写重复的前置检查代码。

@Transactional

当你在方法上使用 @Transactional 注解时,Spring AOP(面向切面编程)会自动地为这些方法生成一个代理对象。这个代理对象会在调用方法之前执行事务管理的逻辑,确保方法执行前后能正确地开始和提交或回滚事务。

实现原理:

  1. 配置:你需要在Spring配置文件中启用AOP支持,并且使用@EnableAutoConfiguration或者@ComponentScan注解扫描并管理你的组件。

    <context:component-scan base-package="com.example"/>
    <aop:aspectj-autoproxy/>
    

    或者

    @SpringBootApplication
    @ComponentScan
    @EnableAutoConfiguration
    public class MyApplication {
        public static void main(String[] args) {
            SpringApplication.run(MyApplication.class, args);
        }
    }
    
  2. 使用事务切面:Spring提供了一个事务切面类 TransactionAspectSupport 或者自定义一个继承 TransactionAspectSupport 的类,并在类中配置事务管理器(TransactionManager)。

    @Aspect
    public class TransactionAspect extends TransactionAspectSupport {
        @Autowired
        private DataSource dataSource;
    
        @Autowired
        private PlatformTransactionManager transactionManager;
    }
    
  3. 定义事务:在需要支持事务的方法上使用 @Transactional 注解。

    @Service
    public class MyService {
        @Transactional
        public void performTransaction() {
            // 业务逻辑
        }
    }
    
  4. 代理生成:Spring会自动识别这些 @Transactional 方法,并生成代理类。这个代理类会实现 InvocationHandler 接口,并在调用实际方法之前检查事务状态。

    当调用 performTransaction() 方法时,如果当前没有事务,则会开始一个新的事务;如果已经有事务,则在当前事务上下文中执行方法。方法执行完毕后,事务会根据调用 commit()rollback() 方法来确定是否提交或回滚事务。

总结:

实际上,当你在方法上使用 @Transactional 注解时,Spring会确保该方法被代理,使其能够正确地管理事务。这个代理过程是基于Spring的AOP机制,并且是在运行时动态生成的,无需开发者在类定义或方法声明中添加额外的代码。

类内部方法调用,会导致AOP失效吗?

在使用AOP(面向切面编程)时,直接在类方法内部调用其他方法并不会导致AOP失效。AOP的代理机制主要应用于类的实例化方法(如构造函数、初始化方法等)和实例方法,以及类的静态方法,只要这些方法被定义在代理对象上,那么无论它们内部调用其他方法,仍然能捕获到对应的切面逻辑。

然而,有几点需要特别注意:

  1. 方法调用层级:AOP代理只会在方法被外部直接调用时生效。如果在方法内部调用另一个方法,且这个调用是作为原始方法的一部分执行的,那么AOP仍然能作用于外部调用方法时。但是,嵌套调用的内部方法不会自动被AOP代理捕获,除非这些内部方法也被显式地用@Pointcut或者@Before@Around等注解定义为切点。

  2. 类的属性和静态方法:AOP对类的属性和静态方法的访问通常不会直接应用切面逻辑,除非使用特殊的切点(如@Around)来进行动态环绕处理或使用@Pointcut定义切点时考虑了静态方法的情况。

  3. 性能和资源消耗:在类内部方法调用中频繁添加切点可能会增加性能开销和内存消耗,因为每个调用都会创建额外的对象,并执行额外的逻辑。在设计时应权衡其对系统性能的影响。

  4. 测试和调试:内部调用在测试中可能会增加复杂性,因为它们可能绕过预期的切面逻辑。确保测试覆盖和调试时能够清楚地看到所有预期的AOP行为。

总之,类内部方法调用一般不会导致AOP失效,但需要正确地使用切点(如@Before@Around@Pointcut)来确保所有需要覆盖的逻辑都能够被AOP机制捕获。对于性能和测试考虑,设计时应有意识地考虑这些因素。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
内部调用导致AOP失效:

在这里插入图片描述
@Transactional事务失效也是类似的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2052216.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JSON Web Token (JWT): 理解与应用

JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;它定义了一种紧凑且自包含的方式&#xff0c;用于在各方之间以JSON对象的形式安全地传输信息。JWT通常用于身份验证和授权目的&#xff0c;因为它可以使用JSON对象在各方…

4.5、配置vtp域

一、了解vtp域 VTP&#xff08;VLAN Trunking Protocol&#xff09;域是一个在网络中用于管理和同步VLAN配置信息的概念。它使得多个交换机可以在同一VTP域中共享VLAN信息&#xff0c;从而简化了VLAN的配置和管理。 三种主要模式 Server模式&#xff1a; 交换机可以创建、修…

Nginx的进程模型:Master-Worker架构解析

Nginx的进程模型&#xff1a;Master-Worker架构解析 一、Master-Worker架构概述二、Master进程的职责三、Worker进程的特点四、与Apache进程模型的对比 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Nginx作为高性能Web服务器&#xff0c…

代码随想录算法训练营day45:动态规划part12:115.不同的子序列;583. 两个字符串的删除操作;72. 编辑距离

目录 115.不同的子序列 分析&#xff1a; 583. 两个字符串的删除操作 72. 编辑距离 115.不同的子序列 力扣题目链接(opens new window) 给定一个字符串 s 和一个字符串 t &#xff0c;计算在 s 的子序列中 t 出现的个数。 字符串的一个 子序列 是指&#xff0c;通过删除…

初识Linux · 基本指令(1)

目录 前言&#xff1a; 基本指令 1.1 pwd 1.2 ls 1.3 mkdir cd clear 1.4 touch 1.5 ls部分补充 1.6 whoami 1.7 有关目录以及路径 前言&#xff1a; 今天是Linux系列的第一章节&#xff0c;对于Linux的主线学习大概会更新两个半月左右&#xff0c;中间穿插着算法…

vue中 在scoped下通过@import引入scss的作用域?

<style lang"scss" src"./index.scss" scoped></style>人工智能学习网站 https://chat.xutongbao.top

nbcio-boot基于flowable6.7.2的流程模型版本管理-前端与界面

更多技术支持与服务请加入我的知识星球。 这部分主要讲前端与功能界面方面 1、首先增加发布列表与修改状态api接口 // 查询流程发布列表 export function listPublish(query) {return request({url: /flowable/definition/publishList,method: get,params: query})}// 激活/挂…

pytorch之nn.Module使用介绍

在 PyTorch 中&#xff0c;nn.Module 是所有神经网络模型的基类&#xff0c;提供了许多重要的成员函数。以下是一些常用的成员函数及其功能&#xff1a; 1. __init__(self) 描述&#xff1a;初始化模块。在用户定义的模型中&#xff0c;通常用来定义层和其他模块。 示例&…

【hot100篇-python刷题记录】【最大子数组和】

R5-普通数组 印象题&#xff0c;讲思路&#xff1a; 1.0个元素&#xff0c;返回0 2.将从left到right的计算简化为为left-mid&#xff0c;mid1-right 以及left-mid-right 3者的最大值&#xff08;因为有负数&#xff09; 3.上面左右两边的计算可以递归调用本身函数&#xff0…

第二十二节、创建人物状态栏

一、可视化插件 在层级面板名字加上对应的图标&#xff0c;会显示颜色&#xff0c;需要运行一下 二、UI 1、创建一个画布 由于使用新的新输入系统&#xff0c;需要替换一下 2、设置锚点 作用是&#xff1a;当屏幕分辨率更改后&#xff0c;ui图标不会位移 3、设置填充 4、制…

tomcat 运行javaweb项 提示无法将资源添加到Web应用程序缓存解决方法

javaweb项目tomcat启动提示web资源缓存不足&#xff0c;具体如下&#xff0c;不影响项目运行 15-Aug-2024 13:35:20.200 警告 [localhost-startStop-1] org.apache.catalina.webresources.Cache.getResource 无法将位于[/WEB-INF/classes/web-vue2/ssdev/ux/login/style/font/f…

2000-2022年 上市公司代理成本(原始数据、上市公司代理成本的最终结果、do文件,参考文献等等)

上市公司代理成本&#xff08;2000-2022年&#xff09; 上市公司的代理成本是公司治理中一个重要的概念&#xff0c;它涉及到公司内部不同利益相关者之间的利益冲突和协调问题。主要包含以下几个方面&#xff1a; 监督成本&#xff1a;股东为了确保经理人的行为符合公司和股东的…

VR游戏移植到Apple Vision Pro的技术挑战与解决方案

核心观点: 30Hz手部追踪在90Hz游戏中的适配 是最大挑战,需要创新性解决方案。Vision Pro的独特架构 要求重新思考着色器编译和缓存策略。全沉浸模式下的空间音频实现 需要自定义解决方案。早期适配 可能面临技术限制,但也带来市场先机。学习指南: 深入研究Vision Pro的手部…

分代回收机制

分代回收机制 JVM分代回收策略 JVM分代回收策略就是Java 虚拟机根据对象存活的周期不同&#xff0c;把堆内存划分为几块&#xff0c;一般分为新生代、老年代&#xff0c;永久代&#xff0c;不过永久代在JDK1.8永久移除了&#xff0c;被元空间取代了 新生代 新生代主要是用来…

【docker】docker compose进阶

docker compose docker compose简介docker compose yaml格式1、docker-compose部署tomcat2、docker-compose部署mysql3、docekr-compose部署lnmp项目需求准备依赖文件、配置nginx配置mysql配置php编写docker-compose.yml配置mysql 4、容器部署registry&#xff0c;进行容器上传…

Springboot+公寓信息服务小程序—计算机毕业设计源码无偿分享需要私信20481

摘要 本论文主要论述了如何使用springboot开发一个公寓信息服务小程序&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述公寓信息服务小程序的当前背景以及系统开发的目的&#xff0c;后续…

STL介绍以及string类

什么是STL 是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 STL的六大组件 为什么要学习string类 C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾的一些字符的集合&#xff0c;为了操作方便&am…

3-4 RGB LED(智能应用篇)

3-4 RGB LED&#xff08;智能应用篇&#xff09; 3-4 RGB LEDRGB-LED及电路示例程序效果演示 3-4 RGB LED Led的灯珠和灯带&#xff0c;相当于点和线&#xff08;可以画出丰富否画面&#xff09; 主要介绍led灯珠 RGB-LED及电路 RGB-LED可以发出红、绿、蓝色的光芒&#xff0…

Flutter 09 Future 和 Stream

一、Future 和 Stream 是处理异步操作的两个重要概念&#xff1a; Future&#xff1a; Future 用于表示一个延迟操作的值或错误&#xff0c;即异步操作的结果。通过 Future&#xff0c;可以在异步操作完成后获取其结果。可以使用 async 和 await 关键字来处理 Future&#xf…

Cisco Catalyst 8000v Edge Software, IOS XE Release IOSXE-17.14.01a ED

Cisco Catalyst 8000v Edge Software, IOS XE Release IOSXE-17.14.01a ED Cisco Catalyst 8000V 边缘软件 - 虚拟路由器 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-catalyst-8000v/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&…