AOP原理

本文深入解析了面向切面编程(AOP)技术,介绍了其通过预编译方式和运行期动态代理实现在不修改源代码情况下给程序添加功能的原理。探讨了AOP在日志记录、事务处理、权限管理等领域的应用,并详细分析了Spring框架中AOP的两种实现方式:接口动态代理和CGLIB子类继承。
AOP简介

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。

AOP应用范围

日志记录,跟踪,优化和监控,事务的处理,持久化,如数据库连接池的管理,系统统一的认证、权限管理等

Spring AOP

在Spring 中,虽然引入了AspectJ的语法,但是他本质上使用的是动态代理的方式.但即使是动态代理,也分两种实现模式:

1.使用接口(动态代理)

如果被代理的对象是面向接口编程的,那么Spring直接使用实现这些接口,然后把需要插入的内容在这个接口上下文中插入

使用ProXy,InvocationHandler类中的invoke方法进行实现

public Object invoke(Object proxy, Method method, Object[] args)

LogInterceptor li = new LogInterceptor();  //创建一个Handerler对象li.setTarget(userDAO);   //将Handler对象和被代理对象关联

 /*newProxyInstance参数含义
   * 第一个参数:代理的类加载器,必须和被代理的对象是一个类加载器
   * 第二个参数含义:代理对象要实现的那些接口
   * 第三个参数:指派方法调用的调用处理程序
* */
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);

2.使用继承(CGLIB)

如果被代理的对象没有基于接口编程,那么Spring会调用cglib库,通过子类继承的方式,动态插入需要的内容,并且调用父类的方法实现

cglib内部拥有一个小的字节码处理框架asm,来转换字节码生成新的类.所以spring调用了cglib,相当于生成了一个被代理对象的子类,来取代被代理对象.

转载于:https://www.cnblogs.com/wudahai/p/7002300.html

### AOP(面向切面编程)工作原理 #### 定义与概念 AOP 即面向切面编程,是对 OOP 的一种补充而非替代[^1]。这种编程范式旨在处理程序中的横切关注点,即那些跨越多个模块或类的功能,比如日志记录、性能监控、安全性和事务管理等。 #### 关键术语解释 - **连接点(Join Point)**:指应用程序执行过程中的特定位置,在这里可以插入额外的行为。 - **通知(Advice)**:定义了当某个连接点被触发时应采取的动作。常见的有前置通知(Before Advice),后置返回通知(After Returning Advice),异常抛出通知(Around Advice)等。 - **切入点(Pointcut)**:用于指定哪些连接点应该应用该通知的表达式或者模式匹配规则。 - **方面(Aspect)**:包含了通知和切入点定义的对象;它是用来封装横切逻辑的地方。 - **引入(Introduction)**:允许向现有类添加新方法或属性的能力。 #### 工作流程概述 在 Java 生态系统里,Spring 框架提供了对 AOP 支持的主要实现方式——基于代理的方式以及基于注解配置的通知机制[^2]。具体来说: 对于**基于代理的 AOP**而言,Spring 使用 JDK 动态代理或是 CGLIB 库创建目标对象的目标接口/子类实例,并在其上调用的方法前后织入相应的增强处理代码片段。这种方式适用于实现了接口的服务组件。 而对于**基于注解的 AOP**, 开发者可以在源码级别上利用 `@Before`, `@AfterReturning` 等自定义元数据标签标记要拦截的操作并编写对应的处理器函数。编译期或运行时期间会自动扫描这些标注并将它们注册到容器中作为可执行单元参与后续调用链路。 最后值得注意的是,借助于 Spring AOP, 可以有效地将业务功能同通用型服务隔离开来,从而提高系统的灵活性与可维护性[^3]. ```java // 示例代码展示如何声明一个简单的 Aspect 切面 import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logMethodCall() { System.out.println("Logging method call..."); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值