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

【Java基础】AOP与注解

一、注解

1、注解定义

注解本质上是一个实现了annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。通过反射获取注解时,返回的是Java运行时生成的动态代理对象。

// 定义注解@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public@interfaceMyAnnotation{Stringvalue()default"default";intcount()default0;}// 编译后:注解本质是一个接口,继承自AnnotationpublicinterfaceMyAnnotationextendsjava.lang.annotation.Annotation{Stringvalue();intcount();}

2、注解作用域和作用范围

2.1 作用域 (@Retention)

根据作用域,可以分为如下三类:

源码级:只在源码中存在,编译后会不会保留,(@Retention(RetentionPolicy.SOURCE))。

类文件级别注解:保留在.class文件中,但运行时不可见,(@Retention(RetentionPolicy.CLASS))。

运行时注解:保留在.class文件中,只有这个作用域可以通过反射在运行时访问(@Retention(RetentionPolicy.RUNTIME))。

2.2 作用范围

作用范围有方法、属性、类

二、AOP

1. 定义切面类

切面类需使用@Aspect标识,并纳入 Spring 容器管理:

@Aspect @Component @Slf4j public class CacheAspect { }

2. 定义切点(Pointcut)

切点用于描述哪些方法/类/连接点需要被拦截。


2.1 常见 Pointcut 表达式

2.1.1@annotation

匹配方法上标记了指定注解的连接点:

// 匹配所有带 @CacheAble 注解的方法 @Pointcut("@annotation(org.example.aop.CacheAble)") public void cacheAbleCut(){}

技巧
可在 Advice 入参中直接绑定注解对象:

@Around("cacheAbleCut() && @annotation(cacheAble)") public Object around(ProceedingJoinPoint jp, CacheAble cacheAble) { ... }

这样可以直接获取注解属性值,无需手动反射。


2.1.2execution

根据方法签名匹配:

// 匹配所有公共方法 @Pointcut("execution(public * *(..))") public void anyPublicMethod() {} // 匹配所有以 set 开头的方法 @Pointcut("execution(* set*(..))") public void anySetMethod() {} // 匹配 com.example.service 包下所有类的所有方法 @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} // 匹配 UserDao 接口的所有实现方法 @Pointcut("execution(* com.example.dao.UserDao.*(..))") public void userDaoMethods() {} // 匹配返回值类型为 User 的方法 @Pointcut("execution(com.example.model.User *(..))") public void methodsReturningUser() {}

2.1.3@within@target

匹配类级别注解:

// 匹配带 @Service 注解类中的所有方法 @Pointcut("@within(org.springframework.stereotype.Service)") public void serviceAnnotationMethods() {} // 匹配目标对象带 @Repository 注解的连接点 @Pointcut("@target(org.springframework.stereotype.Repository)") public void repositoryAnnotationMethods() {}

区别:

  • @within→ 检查声明类是否有注解
  • @target→ 检查运行时目标类是否有注解(Spring 代理场景可能不同)

2.1.4 组合切点

支持&&(与)、||(或)、!(非):

// 在 service 包中且为公共方法 @Pointcut("serviceMethods() && anyPublicMethod()") public void servicePublicMethods() {} // service 包 或 dao 包方法 @Pointcut("serviceMethods() || daoMethods()") public void serviceOrDaoMethods() {} // 非事务性 service 方法 @Pointcut("serviceMethods() && !transactionalMethods()") public void serviceNonTransactionalMethods() {}

2.2 其他常用匹配方式

2.2.1args

绑定方法参数:

@Pointcut("execution(* com.example..*(..)) && args(userId,..)") public void methodWithUserIdArg(String userId) {}

Advice 可直接接收参数:

@Before("methodWithUserIdArg(userId)") public void logUser(String userId) { ... }
2.2.2this/target
  • this(proxy):绑定代理对象
  • target(obj):绑定真实目标对象
@Around("this(proxy) && target(service)") public Object around(ProceedingJoinPoint jp, Object proxy, MyService service) { ... }

3.定义切面

在 AOP 中,切面逻辑主要通过以下几种Advice来实现:

通知类型注解作用时机
前置通知@Before目标方法执行前
后置通知@After目标方法执行后(无论是否异常)
返回通知@AfterReturning目标方法成功返回后
异常通知@AfterThrowing目标方法抛出异常后
环绕通知@Around在目标方法前后都可执行,并可决定是否执行目标方法

​ 其中ProceedingJoinPoint是JoinPoint的子类,由于Around需要执行源方法,ProceedingJoinPoint针对@Around环绕通知提供了proceed()来调用源方法。

3.1 前置通知 @Before

@Before("cacheAbleCut()")publicvoidbeforeMethod(JoinPointjoinPoint){log.info("执行前置通知: 方法 = {}, 参数 = {}",joinPoint.getSignature().getName(),Arrays.toString(joinPoint.getArgs()));}

3.2 后置通知 @After

@After("cacheAbleCut()")publicvoidafterMethod(JoinPointjoinPoint){log.info("执行后置通知: 方法 = {}",joinPoint.getSignature().getName());}

3.3 返回通知 @AfterReturning

@AfterReturning(pointcut="cacheAbleCut()",returning="result")publicvoidafterReturning(JoinPointjoinPoint,Objectresult){log.info("方法 {} 成功返回,返回值 = {}",joinPoint.getSignature().getName(),result);}

3.4 异常通知 @AfterThrowing

@AfterThrowing(pointcut="cacheAbleCut()",throwing="ex")publicvoidafterThrowing(JoinPointjoinPoint,Throwableex){log.error("方法 {} 抛出异常: {}",joinPoint.getSignature().getName(),ex.getMessage(),ex);}

3.5 环绕通知 @Around

@Around是功能最强的通知,可以控制方法执行与否,并在执行前后做处理:

@Around("cacheAbleCut()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{log.info("环绕通知开始 - 方法: {}",pjp.getSignature().getName());longstartTime=System.currentTimeMillis();// 执行目标方法Objectresult=pjp.proceed();longendTime=System.currentTimeMillis();log.info("环绕通知结束 - 耗时: {}ms",(endTime-startTime));// 返回的即最终方法执行后返回的结果,可以自定义随意返回returnresult;}
高级用法:绑定注解实例

如果希望直接在环绕通知的方法参数中获取到目标方法上的注解对象,可以这样写:

@Around("aopPoint() && @annotation(rateLimiterAccessInterceptor)")publicObjectdoRouter(ProceedingJoinPointjp,RateLimiterAccessInterceptorrateLimiterAccessInterceptor)throwsThrowable{log.info("限流检查: key={}, permits={}",rateLimiterAccessInterceptor.key(),rateLimiterAccessInterceptor.permits());returnjp.proceed();}

说明

  • && @annotation(rateLimiterAccessInterceptor)
    限定切点只匹配带有该注解的方法,并且将注解实例注入到参数中。
  • 方法参数RateLimiterAccessInterceptor rateLimiterAccessInterceptor
    直接就是方法上真实存在的注解对象,不需要手动反射getMethod()getAnnotation()

示例目标方法:

@RateLimiterAccessInterceptor(key="userLogin",permits=5)publicvoidlogin(Stringusername){// 登录逻辑}

执行时 AOP 会自动把@RateLimiterAccessInterceptor注解实例注入到doRouter()的第二个参数中。

http://www.jsqmd.com/news/144852/

相关文章:

  • 文书生成Agent+案卷评查Agent+归纳分析Agent,推动烟草行业向更高效、更精准的方向演进
  • 14、Vue Mixin 源码分析与使用场景详解
  • 小家电Type-C受电端诱骗PD充电器获取5V9V12V15V20V供电--应用案例
  • 金融风控模型的鲁棒性验证:软件测试从业者的实践指南
  • 2026初级药师网课推荐:全套资源助力轻松通关 - 资讯焦点
  • 上海哪里可以开病例证明病假条
  • 学长亲荐10个AI论文软件,本科生搞定毕业论文格式规范!
  • 15、Vue 修饰符完全指南
  • PD协议诱骗芯片工作原理,Type-C充电器出不来电压是什么原因?
  • 医师资格证机构怎么挑?选对引路人轻松备考! - 资讯焦点
  • 2025最新!自考党必看10个AI论文工具测评与推荐
  • 除了 gcc/g++,还有哪些常用的 C/C++ 编译器?
  • 中烟创新荣获“2025年中国人工智能行业创新力企业百强”和“中国人工智能行业十大创新力产品”
  • AI论文生成器测评:6款工具实测,20分钟生成万字问卷类论文+真实参考文献,哪款最靠谱?
  • 特易资讯外贸资讯宝突破数据局限!新上验证买家推荐功能,助力企业抢占欧美日韩市场 - 资讯焦点
  • LongCat-Flash与GLM-4.6V,昇腾CANN异构计算深水区突围详解
  • Day41综合案例--alloyTeam
  • 剪映6.0.1 版本免安装 免费剪辑旧版本,免费体验字幕识别
  • 2026年CIO做AI规划时的3个关键点
  • Nature教你读文献:用AI打造超强文献阅读工作流,不光速度快还专业!
  • 深度测评:备考主管护师听哪个老师的课好? - 资讯焦点
  • 11、v-if和v-for的优先级是什么?
  • 高效能10款项目管理系统排行榜:高效率运转的核心利器
  • 智能体进化方向:Skill即场景,Skill即产品
  • 医师资格证优质机构选择干货 专业建议助你择优 - 资讯焦点
  • AI聊天高手的五招秘传:让大模型从话痨变智者
  • 鸿蒙全生态融合与商业化落地终极实战
  • 空气能行业2025年度十大品牌权威榜单总结 - 资讯焦点
  • Comsol微小倾斜造就极致手性:连续体束缚态内秉手性的探究
  • 强强联手!天洑软件资助西工大航模队