跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Spring AOP实现
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Spring AOP实现 = == 介绍 == '''Spring AOP(面向切面编程)'''是Spring框架的核心模块之一,用于将横切关注点(如日志、事务管理、安全等)与核心业务逻辑分离。通过AOP,开发者可以在不修改原有代码的情况下,动态地将额外行为织入到程序的特定位置(如方法调用前后)。Spring AOP基于代理模式实现,支持注解和XML配置两种方式。 == AOP核心概念 == * '''切面(Aspect)''':横跨多个类的模块化关注点(如日志模块)。 * '''连接点(Join Point)''':程序执行过程中的特定点(如方法调用)。 * '''通知(Advice)''':在连接点执行的动作(如前置通知`@Before`)。 * '''切点(Pointcut)''':匹配连接点的表达式(如`execution(* com.example.service.*.*(..))`)。 * '''目标对象(Target Object)''':被代理的原始对象。 * '''织入(Weaving)''':将切面应用到目标对象的过程。 <mermaid> classDiagram class TargetObject { +method() } class Proxy { +method() } class Aspect { +advice() } TargetObject <|-- Proxy Aspect ..> Proxy : 织入 </mermaid> == 实现方式 == === 1. 基于注解的AOP === 通过`@Aspect`注解定义切面,结合通知注解实现具体逻辑。 <syntaxhighlight lang="java"> @Aspect @Component public class LoggingAspect { // 定义切点:匹配Service层所有方法 @Pointcut("execution(* com.example.service.*.*(..))") private void serviceLayer() {} // 前置通知 @Before("serviceLayer()") public void logBefore(JoinPoint joinPoint) { System.out.println("调用方法: " + joinPoint.getSignature().getName()); } // 返回后通知 @AfterReturning(pointcut = "serviceLayer()", returning = "result") public void logAfterReturning(Object result) { System.out.println("方法返回: " + result); } } </syntaxhighlight> **输出示例:** <pre> 调用方法: getUserById 方法返回: User{id=1, name='Alice'} </pre> === 2. 基于XML配置的AOP === 通过`<aop:config>`标签定义切面和通知。 <syntaxhighlight lang="xml"> <bean id="loggingAspect" class="com.example.aspect.LoggingAspect"/> <aop:config> <aop:aspect ref="loggingAspect"> <aop:pointcut id="serviceMethods" expression="execution(* com.example.service.*.*(..))"/> <aop:before method="logBefore" pointcut-ref="serviceMethods"/> </aop:aspect> </aop:config> </syntaxhighlight> == 通知类型 == Spring AOP支持五种通知: {| class="wikitable" |- ! 注解 !! 说明 !! 等效XML标签 |- | `@Before` || 方法执行前触发 || `<aop:before>` |- | `@After` || 方法执行后触发(无论是否异常) || `<aop:after>` |- | `@AfterReturning` || 方法正常返回后触发 || `<aop:after-returning>` |- | `@AfterThrowing` || 方法抛出异常后触发 || `<aop:after-throwing>` |- | `@Around` || 包围方法执行(可控制流程) || `<aop:around>` |} == 实际案例:性能监控 == 以下示例展示如何使用`@Around`通知统计方法执行时间: <syntaxhighlight lang="java"> @Aspect @Component public class PerformanceAspect { @Around("execution(* com.example.service.*.*(..))") public Object measureTime(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); // 执行目标方法 long endTime = System.currentTimeMillis(); System.out.printf("方法 %s 执行耗时: %d ms%n", joinPoint.getSignature().getName(), endTime - startTime); return result; } } </syntaxhighlight> **数学表达**:<br> 计算时间差的公式:<math>\Delta t = t_{end} - t_{start}</math> == 代理机制 == Spring AOP默认使用JDK动态代理(需实现接口)或CGLIB代理(针对类)。可通过配置强制使用CGLIB: <syntaxhighlight lang="java"> @EnableAspectJAutoProxy(proxyTargetClass = true) </syntaxhighlight> == 限制与最佳实践 == * '''限制''': * 仅支持方法级别的连接点(不支持字段/构造器)。 * 切面不能应用于`final`类或方法。 * '''最佳实践''': * 将切面逻辑与业务代码解耦。 * 避免在切面中编写复杂业务逻辑。 * 使用明确的切点表达式减少匹配范围。 == 总结 == Spring AOP通过代理模式实现横切关注点的模块化,显著提升代码可维护性。掌握其核心概念(切面、通知、切点)和实现方式(注解/XML)是构建松耦合应用的关键技能。 [[Category:后端框架]] [[Category:Spring]] [[Category:Spring AOP]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)