跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Spring AOP代理
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Spring AOP代理 = '''Spring AOP代理'''(Spring AOP Proxy)是Spring框架中实现面向切面编程(AOP)的核心机制之一。它通过动态代理技术,在运行时为目标对象创建代理对象,从而在不修改原始代码的情况下,为方法调用添加横切关注点(如日志、事务管理等)。本文将详细介绍Spring AOP代理的工作原理、实现方式以及实际应用。 == 概述 == Spring AOP代理的核心思想是通过代理模式拦截方法调用,并在方法执行前后插入额外的逻辑。Spring支持两种代理方式: * '''JDK动态代理''':基于接口的代理,要求目标类实现至少一个接口。 * '''CGLIB代理''':基于子类化的代理,适用于没有实现接口的类。 代理对象在运行时生成,对调用者透明,使得开发者可以专注于业务逻辑,而将横切关注点(如日志、安全等)与业务代码解耦。 == 代理类型 == === JDK动态代理 === JDK动态代理是Java标准库提供的代理机制,通过`java.lang.reflect.Proxy`类实现。它要求目标对象必须实现至少一个接口。 ==== 代码示例 ==== <syntaxhighlight lang="java"> public interface UserService { void saveUser(); } public class UserServiceImpl implements UserService { @Override public void saveUser() { System.out.println("保存用户信息"); } } public class LoggingAspect implements InvocationHandler { private Object target; public LoggingAspect(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法调用前: " + method.getName()); Object result = method.invoke(target, args); System.out.println("方法调用后: " + method.getName()); return result; } } // 使用JDK动态代理 UserService userService = (UserService) Proxy.newProxyInstance( UserService.class.getClassLoader(), new Class[]{UserService.class}, new LoggingAspect(new UserServiceImpl()) ); userService.saveUser(); </syntaxhighlight> ==== 输出 ==== <pre> 方法调用前: saveUser 保存用户信息 方法调用后: saveUser </pre> === CGLIB代理 === CGLIB(Code Generation Library)是一个强大的代码生成库,Spring使用它来为没有实现接口的类创建代理。CGLIB通过生成目标类的子类来实现代理。 ==== 代码示例 ==== <syntaxhighlight lang="java"> public class ProductService { public void updateProduct() { System.out.println("更新产品信息"); } } public class CglibProxy implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("CGLIB代理 - 方法调用前: " + method.getName()); Object result = proxy.invokeSuper(obj, args); System.out.println("CGLIB代理 - 方法调用后: " + method.getName()); return result; } } // 使用CGLIB代理 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(ProductService.class); enhancer.setCallback(new CglibProxy()); ProductService productService = (ProductService) enhancer.create(); productService.updateProduct(); </syntaxhighlight> ==== 输出 ==== <pre> CGLIB代理 - 方法调用前: updateProduct 更新产品信息 CGLIB代理 - 方法调用后: updateProduct </pre> == 代理选择机制 == Spring AOP根据目标对象的特性自动选择代理方式: * 如果目标对象实现了接口,默认使用JDK动态代理。 * 如果目标对象未实现接口,则使用CGLIB代理。 * 可以通过配置强制使用CGLIB代理(`@EnableAspectJAutoProxy(proxyTargetClass = true)`)。 <mermaid> graph TD A[目标对象] --> B{是否实现接口?} B -->|是| C[JDK动态代理] B -->|否| D[CGLIB代理] </mermaid> == 实际应用场景 == Spring AOP代理广泛应用于以下场景: 1. '''日志记录''':在方法调用前后记录日志。 2. '''事务管理''':通过`@Transactional`注解实现声明式事务。 3. '''性能监控''':统计方法执行时间。 4. '''安全控制''':检查方法调用的权限。 === 事务管理示例 === <syntaxhighlight lang="java"> @Service public class OrderService { @Transactional public void createOrder() { System.out.println("创建订单"); // 数据库操作 } } </syntaxhighlight> Spring会为`OrderService`创建代理,在`createOrder()`方法调用时自动开启和提交事务。 == 性能考虑 == * JDK动态代理生成速度较快,但调用效率略低于CGLIB。 * CGLIB在首次生成代理类时较慢,但后续调用效率更高。 * CGLIB会生成额外的子类,可能增加内存开销。 == 数学表示 == 代理模式可以形式化表示为: <math> \begin{align} Proxy(m) &= Pre(m) \circ m \circ Post(m) \\ \text{其中} \\ Pre(m) &: \text{方法调用前的增强逻辑} \\ Post(m) &: \text{方法调用后的增强逻辑} \\ m &: \text{原始方法} \end{align} </math> == 总结 == Spring AOP代理是AOP实现的关键技术,通过动态代理机制实现了横切关注点与业务逻辑的分离。理解JDK动态代理和CGLIB代理的区别及适用场景,有助于开发者更好地利用Spring AOP解决实际问题。 [[Category:后端框架]] [[Category:Spring]] [[Category:Spring AOP]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)