当前位置: 首页 > article >正文

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

在这里插入图片描述


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


一、事务管理相关

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

示例

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

二、异步任务相关

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

示例

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

三、缓存相关

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

示例

@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 类结合使用。

示例

@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 类中通过代理保证单例。

示例

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserServiceImpl(orderService()); // 代理确保单例
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl();
    }
}

六、安全相关

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

示例

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

七、重试机制

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

示例

@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.kler.cn/a/590197.html

相关文章:

  • matlab 正态分布
  • Flink State 是处理有状态流计算的核心机制,其典型应用场景及具体说明
  • 正则表达式小结
  • Redis-锁-商品秒杀防止超卖
  • HTML深度解读
  • 视频转音频, 音频转文字
  • 物联网(IoT)架构中,平台层的应用与技术
  • Spring Security 教程:从入门到精通(含 OAuth2 接入)
  • 硬件驱动——51单片机:独立按键、中断、定时器/计数器
  • linux自律 第 40 天
  • docker可视化之dpanel
  • Android的消息机制
  • 黑马商城完成随笔
  • SpringBoot 第一课(Ⅲ) 配置类注解
  • 网页制作18-Javascipt图像特效の图片闪烁
  • Python + Qt Designer构建多界面GUI应用程序:Python如何调用多个界面文件
  • Qt常用控件之网格布局QGridLayout
  • 使用 GetX 实现状态管理:同一页面和不同页面之间的数据变化
  • 【Unity6打包Android】游戏启动的隐私政策弹窗(报错处理)
  • VSTO(C#)Excel开发12:多线程的诡异