面向切面编程(Aspect Oriented Programming) 是软件编程思想发展到一定阶段的产物,是面向对象编程的有益补充。AOP一般适用于具有横切逻辑的场合,如访问控制、事务管理、性能检测等。

日志、异常处理、事务控制等都是一个健壮的业务系统所必须的。但是为了保证系统健壮可用,就要再众多业务方法中反复编写类似的代码,使得原本就很复杂的业务处理代码变得更加复杂。业务功能的开发者还要考两次这些额外的代码是否处理正确,是否有遗漏的地方,如果需要修改日志信息的格式或者安全验证的规则,或者再增加辅助功能,都会导致业务代码频繁而大量的修改。

面向切面编程,就是在不改变原程序的基础上为代码增加新的功能,对代码段进行增强处理。他的设计思想来源于代理设计模式。

1.在原对象方法之前插入的增强处理为前置增强

2.该方法执行完以后插入的增强处理为后置增强

3.环绕在方法前后的增强处理为环绕增强,是最强大的增强处理,可以获取或者修改目标方法的参数、返回值、异常处理、甚至决定目标方法是否执行。

4.该方法抛出异常时的增强处理为异常抛出增强

5.最终增强处理,无论方法抛出异常还是正常退出都会得到执行,类似于异常处理机制中finally块的作用,一般用于释放资源

在Springboot中使用注解

需要引入所需要的jar :spring-boot-starter-aop

创建一个aop增强处理类

@Slf4j
@Aspect
@Component
public class LoggerAspect { // 匹配 com.lzz.lzzapp.common.user包及子包下所有类的所有方法
@Pointcut("execution(* com.lzz.lzzapp.common.user..*.*(..))")
public void logPointCut(){ }
//前置增强 在连接点执行之前执行的通知
@Before("logPointCut()")
public void before(){
log.info("即将调用业务方法");
}
//最终增强 在连接点执行之后执行的通知(返回通知和异常通知的异常)
@After("logPointCut()")
public void after(){
log.info("业务方法调用完成");
} /**
* 后置增强 在连接点执行之后执行的通知(返回通知)
*/
@AfterReturning(value="logPointCut()",returning="result")
public void doAfterReturning(JoinPoint joinPoint, Object result){
String methodName = joinPoint.getSignature().getName();
log.info("调用"+joinPoint.getTarget()+"的"+methodName+"方法。参数:"+Arrays.toString(joinPoint.getArgs())
+"。方法返回值:"+result);
} /**
* 异常增强 在连接点执行之后执行的通知(异常通知)
*/
@AfterThrowing("logPointCut()")
public void doAfterThrowing(){
log.info("异常处理完成");
} /**
* 环绕增强
*/
@Around("logPointCut()")
public void doAround(ProceedingJoinPoint jp){
log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName()+"方法。参数:"+Arrays.toString(jp.getArgs()));
try {
Object result=jp.proceed();//执行目标方法
log.info("方法返回值:"+result);
}catch (Throwable e){
log.error(jp.getSignature().getName()+"方法发生异常");
e.printStackTrace();
}
} }

使用@Aspect定义切面,@Pointcut定义切入点

切入点匹配的执行点为连接点为JointPoint,Spring会自动注入该实例,通过joinpoint 的getTarget()方法可以得到被代理对象,getSignature()方法返回被代理的目标方法。getArgs()方法返回传递给目标方法的参数数组

对于后置增强,还可以定义一个用于接收被代理方法的返回值,必须在 @AfterReturning 注解中通过returning 属性指定该参数的名称

execution是切入点指示符,他括号中是一个切入点表达式,可以配置要切入的方法,切入点表达式支持模糊匹配

public * addUser(com.entity.User)     * 表示匹配所有类型的返回值
public void *(com.entity.User) * 表示匹配所有方法名
public void addUser(..) .. 表示匹配所有参数个数和类型
* com.user.*.*(..) 表示匹配com.entity包下所有类的所有方法
* com.user..*.*(..) 表示匹配com.entity包及其子包下所有类的所有方法

最新文章

  1. shared memory realm does not exist
  2. python 相关安装和配置
  3. 操作JNI函数以及复杂对象传递
  4. css控制图片自适应大小
  5. 国内物联网平台初探(八):移动云OneNET
  6. tbody 滚动条
  7. OD: Shellcode Encoding
  8. C# Volatile 类
  9. ios实现文字的自适应
  10. Vue学习小结(一)安装依赖与数据来源
  11. JDK下载API文档
  12. ASP.Net在64位环境开发部署常见问题
  13. 根据关键字找进程id
  14. select 和epoll模型区别
  15. 自制URL转换器
  16. 前端性能优化成神之路--图片懒加载(lazyload image)
  17. C#-MaximumSIze,MinimumSize,窗口默认大小范围---ShinePans
  18. 007.FTP虚拟用户访问
  19. redis哨兵机制一(转)
  20. python 三种遍历列表里面序号和值的方法

热门文章

  1. laravel多条件模糊查询
  2. 【Unity|C#】基础篇(9)——匿名函数 / Lambda表达式
  3. liunx 中设置zookeeper 自启动(service zookeeper does not support chkconfig)
  4. python:创建文件夹
  5. CentOS7下升级PHP版本为7.2
  6. 诡异的BUG
  7. Json.Net的介绍与简单实用(兼容2.0/3.0/3.5/4.5/RT)
  8. Android开发模拟器(虚拟机)的连接等操作
  9. Python | 字符串拆分和拼接及常用操作
  10. 题解【洛谷P1347】排序