跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
AOP实现原理
”︁(章节)
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= AOP实现原理 = == 简介 == '''面向切面编程(AOP, Aspect-Oriented Programming)'''是Spring框架的核心功能之一,它通过横向切割关注点(Cross-Cutting Concerns)来增强代码的模块化。AOP允许开发者将日志记录、事务管理、安全控制等与业务逻辑无关的功能从核心业务代码中分离出来,从而提高代码的可维护性和复用性。 Spring AOP的实现基于动态代理机制,主要分为两种方式: * '''JDK动态代理''':针对实现了接口的目标类 * '''CGLIB动态代理''':针对没有实现接口的目标类 == 核心概念 == 以下是AOP中的关键术语: * '''切面(Aspect)''':横切关注点的模块化(如日志模块) * '''连接点(Join Point)''':程序执行过程中的特定点(如方法调用) * '''通知(Advice)''':在连接点执行的动作(如方法前后执行的代码) * '''切入点(Pointcut)''':匹配连接点的表达式 * '''目标对象(Target Object)''':被代理的对象 * '''织入(Weaving)''':将切面应用到目标对象的过程 <mermaid> classDiagram class Aspect { +pointcut() +advice() } class Target { +businessMethod() } Aspect --> Target : 织入 </mermaid> == 实现机制 == === JDK动态代理 === 当目标类实现了接口时,Spring会使用JDK的<code>java.lang.reflect.Proxy</code>类创建代理对象。 <syntaxhighlight lang="java"> // 接口 public interface UserService { void saveUser(); } // 实现类 public class UserServiceImpl implements UserService { public void saveUser() { System.out.println("保存用户"); } } // 代理处理器 public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("前置通知"); Object result = method.invoke(target, args); System.out.println("后置通知"); return result; } } // 使用示例 public class Main { public static void main(String[] args) { UserService target = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new MyInvocationHandler(target) ); proxy.saveUser(); } } </syntaxhighlight> 输出结果: <pre> 前置通知 保存用户 后置通知 </pre> === CGLIB动态代理 === 对于没有实现接口的类,Spring使用CGLIB库通过继承方式创建子类代理。 <syntaxhighlight lang="java"> // 目标类 public class ProductService { public void addProduct() { System.out.println("添加商品"); } } // 方法拦截器 public class MyMethodInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("前置处理"); Object result = proxy.invokeSuper(obj, args); System.out.println("后置处理"); return result; } } // 使用示例 public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(ProductService.class); enhancer.setCallback(new MyMethodInterceptor()); ProductService proxy = (ProductService) enhancer.create(); proxy.addProduct(); } } </syntaxhighlight> 输出结果: <pre> 前置处理 添加商品 后置处理 </pre> == 代理选择策略 == Spring AOP按照以下顺序选择代理方式: # 如果目标对象实现了接口 → 使用JDK动态代理 # 如果目标对象没有实现接口 → 使用CGLIB # 可以通过配置强制使用CGLIB:<code><aop:config proxy-target-class="true"></code> == 实际应用案例 == === 事务管理 === Spring的事务管理就是基于AOP实现的典型例子: <syntaxhighlight lang="java"> @Transactional public void transferMoney(Account from, Account to, double amount) { from.debit(amount); to.credit(amount); } </syntaxhighlight> Spring会在方法执行前开启事务,执行后根据结果提交或回滚事务。 === 性能监控 === 可以创建一个切面来监控方法执行时间: <syntaxhighlight lang="java"> @Aspect @Component public class PerformanceAspect { @Around("execution(* com.example.service.*.*(..))") public Object logPerformance(ProceedingJoinPoint pjp) throws Throwable { long start = System.currentTimeMillis(); Object result = pjp.proceed(); long elapsed = System.currentTimeMillis() - start; System.out.println(pjp.getSignature() + " 执行时间: " + elapsed + "ms"); return result; } } </syntaxhighlight> == 数学原理 == AOP的织入过程可以看作是在程序执行流中插入额外的操作。设原始方法为<math>f(x)</math>,前置通知为<math>g(x)</math>,后置通知为<math>h(x)</math>,则代理后的方法为: <math> f_{proxy}(x) = h(f(g(x))) </math> == 性能考虑 == * JDK动态代理比CGLIB更快,因为它是Java标准库的一部分 * CGLIB在创建代理时较慢,但调用速度与JDK代理相当 * Spring会缓存生成的代理对象以提高性能 == 限制 == * 只能拦截public方法 * 无法拦截final方法(CGLIB通过继承实现) * 自调用问题:同一个类中的方法互相调用不会触发AOP == 总结 == Spring AOP通过动态代理机制实现了面向切面编程,主要特点包括: * 两种实现方式:JDK动态代理和CGLIB * 关注点分离,提高代码模块化 * 广泛应用于事务、日志、安全等场景 * 配置简单,与Spring容器无缝集成 理解AOP的实现原理有助于开发者更好地使用Spring框架并编写更优雅的代码。 [[Category:计算机科学]] [[Category:面试技巧]] [[Category:Spring框架]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)