Spring 中使用代理的注解及机制分析

embedded/2025/3/20 16:05:41/

在这里插入图片描述


Spring 通过动态代理(JDK 或 CGLIB)为特定注解提供功能增强。以下是触发代理的核心注解及其实现机制:


一、事务管理相关

注解代理机制作用与场景注意事项
@TransactionalJDK 动态代理或 CGLIB(默认优先 JDK)声明式事务管理,标注在类或方法上,控制事务的提交、回滚和传播行为。- 需通过代理调用,同类方法直接调用会导致事务失效。
- 默认仅对 RuntimeException 回滚,需显式配置其他异常。
@EnableTransactionManagement无直接代理,启用事务管理支持配合 @Transactional 使用,启用基于代理的事务管理。需与 @Configuration 类结合使用。

示例

java">@Service
public class OrderService {@Transactionalpublic void createOrder(Order order) {// 数据库操作(代理拦截事务)}
}

二、异步任务相关

注解代理机制作用与场景注意事项
@AsyncJDK 动态代理或 CGLIB(默认优先 JDK)标注方法或类,异步执行任务(通过线程池)。- 同类调用需通过代理触发异步逻辑(如 AopContext.currentProxy())。
- 需启用 @EnableAsync
@EnableAsync无直接代理,启用异步支持配合 @Async 使用,激活异步代理生成。可配置线程池参数。

示例

java">@Service
public class TaskService {@Asyncpublic void processTask() {// 异步执行(代理拦截并提交到线程池)}
}

三、缓存相关

注解代理机制作用与场景注意事项
@CacheableJDK 动态代理或 CGLIB(默认优先 JDK)标注方法,缓存方法返回值(根据 Key 匹配缓存)。- 同类调用需通过代理触发缓存逻辑。
- 需启用 @EnableCaching
@CachePut同上更新缓存数据(无论缓存是否存在)。需与 @Cacheable 配合使用。
@CacheEvict同上清除指定缓存条目。可配置 allEntries 清空所有缓存。
@EnableCaching无直接代理,启用缓存支持激活缓存代理生成。需配置缓存管理器(如 Redis)。

示例

java">@Service
public class UserService {@Cacheable(value = "users", key = "#userId")public User getUser(String userId) {// 数据库查询(代理拦截并缓存结果)}
}

四、AOP 切面相关

注解代理机制作用与场景注意事项
@AspectJDK 动态代理或 CGLIB(默认优先 JDK)定义切面类,包含通知(@Before@Around 等)和切入点(@Pointcut)。- 需启用 @EnableAspectJAutoProxy
- 同类调用需通过代理触发切面逻辑。
@EnableAspectJAutoProxy无直接代理,启用 AspectJ 自动代理激活 AOP 代理生成,可配置 proxyTargetClass=true 强制使用 CGLIB。通常与 @Configuration 类结合使用。

示例

java">@Aspect
@Component
public class LogAspect {@Before("execution(* com.xiaolingting.service.*.*(..))")public void logBefore(JoinPoint joinPoint) {// 日志记录(代理拦截方法调用)}
}

五、配置类代理

注解代理机制作用与场景注意事项
@ConfigurationCGLIB 代理(Full 模式)标注配置类,声明 @Bean 方法,通过代理拦截 @Bean 方法调用,确保单例依赖正确注入。- 无此注解时为 Lite 模式(无代理,直接调用)。
- 需避免在 @Bean 方法中直接调用其他 @Bean 方法。
@Bean依赖 @Configuration 的代理机制声明 Bean 实例化逻辑。@Configuration 类中通过代理保证单例。

示例

java">@Configuration
public class AppConfig {@Beanpublic UserService userService() {return new UserServiceImpl(orderService()); // 代理确保单例}@Beanpublic OrderService orderService() {return new OrderServiceImpl();}
}

六、安全相关

注解代理机制作用与场景注意事项
@PreAuthorizeJDK 动态代理或 CGLIB(默认优先 JDK)方法级权限控制(需 Spring Security 支持)。- 需启用 @EnableGlobalMethodSecurity(prePostEnabled = true)
@Secured同上基于角色的权限控制。需显式启用 @EnableGlobalMethodSecurity(securedEnabled = true)

示例

java">@Service
public class AdminService {@PreAuthorize("hasRole('ADMIN')")public void deleteUser(String userId) {// 仅管理员可调用(代理拦截权限校验)}
}

七、重试机制

注解代理机制作用与场景注意事项
@RetryableJDK 动态代理或 CGLIB(默认优先 JDK)标注方法,在抛出指定异常时重试(需 Spring Retry 支持)。- 需启用 @EnableRetry
- 可配置重试次数和退避策略。

示例

java">@Service
@EnableRetry
public class PaymentService {@Retryable(value = PaymentException.class, maxAttempts = 3)public void processPayment() {// 支付失败时自动重试(代理拦截重试逻辑)}
}

总结

Spring 代理机制通过动态生成代理对象,为以下场景提供功能增强:

  1. 事务管理@Transactional
  2. 异步任务@Async
  3. 缓存控制@Cacheable@CachePut@CacheEvict
  4. AOP 切面@Aspect 及相关通知注解。
  5. 配置类单例@Configuration + @Bean
  6. 安全控制@PreAuthorize@Secured
  7. 重试机制@Retryable

核心注意事项

  • 代理触发条件:需确保目标类被 Spring 管理(如 @Component 扫描或手动注册)。
  • 同类调用问题:通过 AopContext.currentProxy() 或重构代码解决。
  • 代理类型选择:优先 JDK 动态代理(接口实现),强制 CGLIB 需配置 proxyTargetClass=true

http://www.ppmy.cn/embedded/174187.html

相关文章

游戏引擎学习第168天

回顾并计划今天的内容 今天我们将进行一些思考工作,回顾一下之前的工作。我们已经在资产处理工具中提取了字体,并展示了如何使用该库。我们有两个版本,一个不使用任何库,适合想要完全不依赖库的用户; 我们今天的任务…

element 样式记录

非完整代码&#xff0c;个人记录 表格分页 pagination,table <el-table :data"tableData" style"width: 100%"><el-table-column prop"id" label"ID" width"75"></el-table-column><el-table-column p…

ubuntu 没有网卡的解决方案

(1) 输入sudo service network-manager stop (2) sudo rm /var/lib/NetworkManager/NetworkManager.state (3) sudo service network-manager start (4) sudo vim /etc/NetWorkManager/NetworkManager.conf&#xff0c;将其中的managedfalse改为managedtrue 或者使用gedit&…

深入探索JVM字节码增强技术与调优实践

引言 Java虚拟机(JVM)是Java程序运行的基石,而字节码增强技术则是JVM生态中一项强大的工具。通过字节码增强,开发者可以在不修改源代码的情况下,动态地修改或增强类的行为。本文将深入探讨字节码增强技术的原理、常用工具,并结合JVM调优和排错实践,帮助开发者更好地理解…

简单几步完成dify的本地搭建

简单几步完成dify的本地搭建

Java 中 LinkedList 的底层数据结构及相关分析

Java 中 LinkedList 的底层数据结构及相关分析 1. 概述 LinkedList 是 Java 集合框架&#xff08;Java Collections Framework&#xff0c;JCF&#xff09;中的一个双向链表实现&#xff0c;它位于 java.util 包下&#xff0c;支持 列表&#xff08;List&#xff09; 和 队列…

Git使用规范

摘要 本文主要讲解Git 提交需遵循相应规范。Pull Request 方面&#xff0c;一个 PR 专注一件事。信息填写中&#xff0c;Title 分仅含一个 commit 和多个 commit 的情况&#xff1b;Content 也有要求。还有其它规范&#xff0c;如连接 issue&#xff0c;pr 完成后要妥善处理&…

设计模式(创建型)-抽象工厂模式

摘要 在软件开发的复杂世界中,设计模式作为解决常见问题的最佳实践方案,一直扮演着至关重要的角色。抽象工厂模式,作为一种强大的创建型设计模式,在处理创建一系列或相关依赖对象的场景时,展现出了独特的优势和灵活性。它通过提供一个创建对象的接口,让开发者能够在不指定…