Spring第三讲:SpringAOP面向切面编程

五、Spring AOP

5、1什么是AOP

AOP(Aspect Orient Programming),面向切面编程,AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向切面编程,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。AOP可以拦截指定的方法并且对方法增强,而且无需侵入到业务代码中,使业务与非业务处理逻辑分离,比如Spring的事务,通过事务的注解配置,Spring会自动在业务方法中开启、提交业务,并且在业务处理失败时,执行相应的回滚策略。

5、2AOP作用

AOP 采取横向抽取机制(动态代理),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。简单的说,AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。

5、3AOP核心信息

  • Aspect(切面):切面是一个类,被@Aspect注解标准或者使用XML配置文件的aop:aspect引用。切面是类,一般在这个类中包含了大量要“织入”目标对象的方法。这些方法会被通知、切点表达式注解,因此也被称为通知方法。

  • Target object(目标对象):目标对象就是被切面盯上,要被“织入”切面方法的对象。实现的方式是Spring AOP利用代理技术(JDK或CGLib)新建一个与目标对象类型相关的新对象,这个新对象称为代理对象(proxy object)。

  • Join point(连接点):就是目标对象被“织入”内容的位置,Spring AOP中连接点只能是目标对象程序执行的节点,也就是执行方法或抛出异常。所以在Spring AOP中,不管是连接点还是"织入"的内容都是方法,只不过连接点是目标对象的方法,织入的内容是切面的方法。

  • Advice(通知):织入内容在连接点执行的动作。例如前置,后置,环绕等。如图所示,一个Advice是前置在切入点的(方法执行),另一个Advice是后置在切入点(方法执行)的,而且那个位置恰好还是连接点抛出了异常。

  • Pointcut(切点):经常与通知写在一起,通过切入点标识符和切入点表达式,匹配可以“织入”的目标对象的连接点。

5、4AOP通知类型

Spring AOP 提供了下面五种通知类型:

  • Before(前置通知):连接点前面执行,不能终止后续流程,除非抛异常

  • AfterReturning(后置通知):连接点正常返回时执行,有异常不执行

  • AfterThrowing(异常通知):连接点方法抛出异常时执行

  • After(最终通知):连接点退出时执行,无论是正常退出还是异常退出

  • Around(环绕通知):围绕连接点前后执行,也能捕获处理异常

5、5Spring AOP实现

pom.xml引入资源

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>5.3.24</version>
</dependency>
<dependency>
  <groupId>aopalliance</groupId>
  <artifactId>aopalliance</artifactId>
  <version>1.0</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.9.19</version>
</dependency>

实现切面类,进行AOP切面处理

public class MyAdvice implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor {

  //SpringAOP前置通知
  @Override
  public void before(Method method, Object[] args, Object target) throws Throwable {

  }

  //SpringAOP后置通知
  @Override
  public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {

  }

  //环绕通知
  @Override
  public Object invoke(MethodInvocation invocation) throws Throwable {
    //前置通知方法
    invocation.proceed();//方法执行
    //后置通知方法
    return null;
  }
}

在spring配置文件applicationContext中加入配置

<aop:config>
  <aop:advisor advice-ref="myAdvice" pointcut="execution(* com.demo.service.*.*(..))"/>
</aop:config>

注解实现AOP切面类编程

@Aspect
@Component
public class MyAspect {

  //设置执行切面的方法
  private final static String EXPRESSION =
    "execution(* com.demo.service.*.*(..))";

  //前置通知
  @Before(EXPRESSION)
  public void beforeAdvice(JoinPoint joinPoint){
    System.out.println("前置通知");
  }


  //后置通知:方法正常执行后,有返回值,执行该后置通知:如果该方法执行出现异常,则不执行该后置通知
  @AfterReturning(value = EXPRESSION,returning = "returnVal")
  public void afterReturningAdvice(JoinPoint joinPoint,Object returnVal){
    System.out.println("后置通知");
  }

  //后置通知
  @After(EXPRESSION)
  public void afterAdvice(JoinPoint joinPoint){
    System.out.println("后置通知");
  }

  //环绕通知
  @Around(EXPRESSION)
  public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("环绕通知的前置通知");
    Object returnVale = joinPoint.proceed();
    System.out.println("环绕通知的后置通知");
    return returnVale;
  }

  // 异常通知:方法出现异常时,执行该通知
  @AfterThrowing(value = EXPRESSION,throwing = "ex")
  public void throwAdvice(JoinPoint joinPoint, Exception ex){
    System.out.println("异常通知开始");
    System.out.println("出现异常:" + ex.getMessage());
    System.out.println("异常通知结束");
  }

}

使用注解配置切面类的applicationContext.xml

<context:component-scan base-package="com.demo"/>
<aop:aspectj-autoproxy/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值