一.AOP框架实战:轻松实现面向切面编程
1. 简介
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,它允许程序员以模块化的方式添加功能到应用程序。AOP框架通过在程序执行的特定时间点插入代码(称之为切面)来实现这一点。
2. AOP框架的核心概念
- 切点(Pointcut): 定义了通知应该应用于哪些方法。
- 通知/切面(Advice): 在连接点执行的代码。
- 连接点(JoinPoint): 目标方法的执行点。
3. AOP框架的应用场景
- 日志记录
- 性能监控
- 事务管理
- 安全检查
4. AOP框架一般这么用
- 定义切点
- 定义通知/切面
- 将切点和通知应用到目标方法
- 创建代理对象
5. AOP框架的优点
- 模块化:AOP框架可以将应用程序的功能模块化,使应用程序更易于维护和扩展。
- 可重用性:AOP框架可以将通知代码重用在多个应用程序中。
- 降低耦合度:AOP框架可以降低应用程序组件之间的耦合度。
6. AOP框架的缺点
- 性能开销:AOP框架可能会引入一定的性能开销。
- 代码复杂度:AOP框架可能会使应用程序的代码变得更加复杂。
7. AOP框架的选型
目前有许多流行的AOP框架可供选择,包括:
- AspectJ
- Spring AOP
- CGLib
在选择AOP框架时,需要考虑以下因素:
- 应用程序的规模和复杂度
- 应用程序的性能要求
- 应用程序的开发语言和平台
二.手把手教你用 Java 编写一个简单的 AOP 框架
1. 手撸 AOP 框架介绍
我最近编写了一个简单的 AOP 框架,它可以帮助程序员轻松地实现面向切面编程。我的 AOP 框架具有以下特点:
- 简单易用: 只需几行代码,即可将通知应用到目标方法。
- 功能强大: 支持多种类型的通知,包括前置通知、后置通知、返回通知、异常通知和环绕通知。
- 可扩展: 可以通过编写自定义的通知来扩展框架的功能。
2.核心代码
2.1切点
/**
* 切点类
* 1.使用切点表达式来指定通知应该应用于哪些方法
* 2.使用 Pointcut 实例来检查方法是否匹配切点表达式
* 3.使用 Pointcut 实例来组合更复杂的切点表达式
* Pointcut 的作用和职责:
* 指定通知应该应用于哪些方法: Pointcut 用于指定通知应该应用于哪些方法。我们可以使用切点表达式来定义 Pointcut。切点表达式是一种特殊的字符串,它可以匹配方法签名。
* 例如,以下切点表达式匹配所有以 save 开头的方法:execution(public void aa.bb.cc.Test.save*(..))
*/
public interface Pointcut {
boolean matches(Object object);
/**
* 表达式
*/
String getPointcutExpression();
/**
* tag对象
*/
void setTag(Object tag);
}
2.2切面
/**
* 切面行接受通知后可执行相应逻辑
*/
public interface Advice {
//执行
void execute(JoinPoint joinPoint) throws Throwable;
//通知配型
Configurator config();
}
2.3连接点
/**
* 连接点类
* 1.向通知传递有关连接点的信息
* 2.在通知中获取有关连接点的信息
* 作用:通知与连接点进行交互,并传递和获取有关连接点的信息,对它进行扩展可获得以下信息。
* 例如,方法调用、字段访问、异常抛出等。JoinPoint 可以传递的信息包括目标对象、方法名、参数、返回值、异常对象等。
* 例如,我们可以使用 JoinPoint 来获取目标对象、方法名、参数、返回值、异常对象等信息。
* 例如,我们可以使用 JoinPoint 来修改方法的参数、返回值或抛出异常
*/
public interface JoinPoint {
Object getTarget();
String getMethodName();
Object[] getArgs();
}
2.4多通知
/**
* 切点类型通知类,定义通知的类型
* 不同的通知有一定的应用场景。
* *环绕通知:
* * 记录日志,性能监控
* * 事务管理,在目标方法执行之前和之后进行事务管理,可以确保目标方法在事务中执行。
* *
* * 异常通知:
* * 记录日志,在目标方法执行之后且抛出异常时记录日志,可以帮助我们了解目标方法的执行情况。
* * 发送邮件,在目标方法执行之后且抛出异常时发送邮件,可以通知相关人员目标方法执行失败。
* * 回滚事务,在目标方法执行之后且抛出异常时回滚事务,可以防止数据不一致。
* *
* * 最终通知:
* * 资源释放,不管目标方法执行是否成功,最终会释放一些资源。
* *
* * 前置通知:
* * 检查权限,在目标方法执行之前检查权限,可以防止未授权用户访问受保护的资源。
* * 初始化资源,在目标方法执行之前初始化资源,可以确保目标方法能够正常执行。
* *
* * 后置通知:
* * 清理资源,在目标方法执行之后清理资源,可以防止资源泄漏。
* * 更新缓存,在目标方法执行之后更新缓存,可以提高应用程序的性能。
*
*/
public enum AdviceType {
BEFORE("before"), // 在方法调用之前执行通知
AFTER("after"), // 在方法调用之后执行通知
AROUND("around"), // 在方法调用前后执行通知
AFTER_THROWING("afterThrowing"), // 在方法抛出异常之后执行通知
AFTER_FINALLY("afterFinally"); // 目标方法无论是否执行成功后执行通知
public enum AROUND_S{
A_BEFORE,A_AFTER
}
private final String name;
AdviceType(String name) {
this.name = name;
}
public String getName() {
return name;
}
private AROUND_S aroundS;
public void setAroundS(AROUND_S aroundS) {