AOP技术

本文深入解析了AOP(面向切面编程)的概念及其在软件开发中的应用价值。通过介绍AOP的基本思想、应用场景及其实现原理,帮助读者理解如何利用AOP来优化代码结构、降低模块间的耦合度,并通过具体示例展示了使用Spring框架实现AOP的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是AOP技术?

AOP: Aspect Oriented Programming 面向切面编程。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

应用场景

日志记录,性能统计,安全控制,事务处理,异常处理等等。

主要的意图

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

注意:AOP不是一种技术,实际上是编程思想。凡是符合AOP思想的技术,都可以看成是AOP的实现。

关注点

重复代码就叫做关注点;

切面

关注点形成的类,就叫切面(类)!
面向切面编程,就是指对很多功能都有的重复的代码抽取,在运行的时候往业务方法上动态植入“切面类代码”。

切入点

执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法; 给指定的类在运行的时候植入切面类代码。

AOP 实现原理

代理设计模式

注解版本实现AOP

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>  开启事物注解权限
@Aspect 指定一个类为切面类
@Pointcut("execution(* com.xiaoming.service.UserService.add(..))")  指定切入点表达式
@Before("pointCut_()") 前置通知: 目标方法之前执行
@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()")  返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()") 异常通知:  出现异常时候执行
@Around("pointCut_()") 环绕通知: 环绕目标方法执行
AopLog
@Component
@Aspect
public class AopLog {
 
      // 前置通知
      @Before("execution(* com.xiaoming.service.UserService.add(..))")
      public void begin() {
           System.out.println("前置通知");
      }
 
      //
      // 后置通知
      @After("execution(* com.xiaoming.service.UserService.add(..))")
      public void commit() {
           System.out.println("后置通知");
      }
 
      // 运行通知
      @AfterReturning("execution(* com.xiaoming.service.UserService.add(..))")
      public void returning() {
           System.out.println("运行通知");
      }
 
      // 异常通知
      @AfterThrowing("execution(* com.xiaoming.service.UserService.add(..))")
      public void afterThrowing() {
           System.out.println("异常通知");
      }
 
      // 环绕通知
      @Around("execution(* com.xiaoming.service.UserService.add(..))")
      public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
           System.out.println("环绕通知开始");
           proceedingJoinPoint.proceed();
           System.out.println("环绕通知结束");
      }
}

XML方式实现AOP

  1. 引入jar文件 【aop 相关jar, 4个】
  2. 引入aop名称空间
  3. aop 配置
    配置切面类 (重复执行代码形成的类)
    aop配置
    拦截哪些方法 / 拦截到方法后应用通知代码
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
 
     <!-- dao 实例 -->
 
     <bean id="userService" class="com.xiaoming.service.UserService"></bean>
     <!-- 切面类 -->
     <bean id="aop" class="com.xiaoming.aop2.AopLog2"></bean>
     <!-- Aop配置 -->
     <aop:config>
         <!-- 定义一个切入点表达式: 拦截哪些方法 -->
         <aop:pointcut expression="execution(* com.xiaoming.service.UserService.*(..))"
              id="pt" />
         <!-- 切面 -->
         <aop:aspect ref="aop">
              <!-- 环绕通知 -->
              <aop:around method="around" pointcut-ref="pt" />
              <!-- 前置通知: 在目标方法调用前执行 -->
              <aop:before method="begin" pointcut-ref="pt" />
              <!-- 后置通知: -->
              <aop:after method="after" pointcut-ref="pt" />
              <!-- 返回后通知 -->
              <aop:after-returning method="afterReturning"
                   pointcut-ref="pt" />
              <!-- 异常通知 -->
              <aop:after-throwing method="afterThrowing"
                   pointcut-ref="pt" />
         </aop:aspect>
     </aop:config>
 
</beans>
AopLog2
public class AopLog2 {
 
      // 前置通知
      public void begin() {
           System.out.println("前置通知");
      }
 
      //
      // 后置通知
      public void commit() {
           System.out.println("后置通知");
      }
 
      // 运行通知
      public void returning() {
           System.out.println("运行通知");
      }
 
      // 异常通知
      public void afterThrowing() {
           System.out.println("异常通知");
      }
 
      // 环绕通知
      public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
           System.out.println("环绕通知开始");
           proceedingJoinPoint.proceed();
           System.out.println("环绕通知结束");
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值