Spring学习:Spring的AOP注解

本文介绍了Spring AOP的注解使用,包括增强类(Advice)的定义,如何将Advice加载到AOP容器,切入点和增强方法的定义,以及在XML文件中动态创建代理对象的步骤。重点讲解了@Aspect、@Component、@Pointcut和各种增强方法注解的用法。

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

一、简介

Spring Aop的注解是在IOC注解基础上,重点突出增强类(Advice)的注解,一个增强类可以看成是一个切面(Aspect),因此,Aop注解的学习,基本上可以是看成增强类所用到的注解的学习。重点需要掌握了解以下几个知识点:

  1. 增强类定义为组件Bean的同时,还需要定义为增强类(切面)的Bean,因此,他需要在@Componen的基础上,再加上注解@Aspec;
  2. 增强类中的增强方法上,可以用注解来定义这个增强方法可以用在哪些切入点上;
  3. 切入点可以映射到一个方法中,这个方法可以是Advice(增强类)中的一个方法,也可以自定义类中定义的一个静态方法,如果切入点还要引入到别的增强类,那么建议使用自定义类的静态方法做为切入点的引用;
  4. 由于目标对象(被代理对象)以及增强类都被加载到AOP容器中,且这个Bean和Aspect都存在注解对这两个Bean的说明,因此,在xml文件中,产生代理对象只需一句代码;

二、增强类(Advice)加载到AOP文件中

Advice是一个增强类,加载到AOP容器的时候,需要配置两个注解。一是他作为一个正常的Bean的注解@Component,另一个是作为一个切面(Advice)@Aspect,具体示例代码如下:


import aop3.pos.StringToUserPropertiesEditor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;


@Component
@Aspect
public class UserAop5Advice {
    // TODO: 2021/6/30 将增强类中的增强方法做为代理对象方法的前置增强 ,切入点的定义是在一个类中,用静态方法引入了切入点
    @Before(value = "UserAspect.aspect()")
    public void beforeAdvice(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        String methodSignatureName = methodSignature.getName();
        Object[] args = joinPoint.getArgs();
        Object target = joinPoint.getTarget();
        System.out.println("beforeAdvice:" + methodSignatureName + ";Args:" + args + ";Target:" + target);
    }

    // TODO: 2021/7/1 这个方法只能适用于切入点的后置,是一个增强类的后置增强方法,需要与注解或者xml命名空间来配合使用
    @AfterReturning(value = "UserAspect.aspect2()",returning = "object")
    public void afterAdvice(JoinPoint joinPoint,Object object){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodSignatureName = methodSignature.getName();
        Object[] args = joinPoint.getArgs();
        Object target = joinPoint.getTarget();
        System.out.println("afterAdvice: methonName:" + methodSignatureName + ";Args:" + args + "; Target:" + target + ";retunValue:" + object);
    }


    // TODO: 2021/7/1 这个增强类方法是环绕增强,以调用目标对象的方法调用为分界线,之前是前置,之后是后置
    @Around(value = "UserAspect.aspect2()")
    public Object beforeAndAfterAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("开启事务处理");
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("结束事务处理");
        return proceed;
    }

    // TODO: 2021/7/1 增强类中的异常处理增强,这是由参数决定的,方法名是可以随意取的,他必须和注解或者命名空间配合使用
    @AfterThrowing(value = "UserAspect.aspect2()",throwing = "exception")
    public void exceptionAdvice(JoinPoint joinPoint,Exception exception){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String methodSignatureName = methodSignature.getName();
        Object[] args = joinPoint.getArgs();
        Object target = joinPoint.getTarget();
        System.out.println("ExceptionAdvice: methonName:" + methodSignatureName + ";Args:" + args + "; Target:" + target + ";exception:" + exception);
    }
}

三、增强类的增强方法切入点及在切入点位置的定义

指的是,增强类中的增强方法可用于哪些切入点。在知道切入点的时候,还需要明确增强方法在切入点的位置是前置、后置、环绕还是异常,因此,在定义增强方法中的切入点注解是与切入点位置是相对应的,也就是说,增强类中增强方法所用的注解包含两层的意思:

  • 明确增强方法可用于哪些切入点
  • 明确增强方法在切入点的具体位置(前置、后置、环绕和异常)
    以下表格所表示注解为增强类中增强方法的注解
增强注解说明
@Before(切点方法())前置增强
@AfterReturning后置增强
@Around环绕增强
@AfterThrowing异常增强
  • 切入点方法的映射
    可以用一个方法映射到切和点,这个方法可以增强类(Advice)中的一个方法,也可以自定义类中一个静态方法,其核心还是在方法上用一个@Pointcut(切点表达式)注解,参数中的切点表达式是Aspect表达式,主要有两个方法:within()方法和execution()方法
// TODO: 2021/6/30 这是一个自定义类,自定义类中的静态方法映射到一个切入点 
public class UserAspect {

    @Pointcut(value = "execution(* aop5.impl.*.*(..))")
    public static void aspect(){}
}

在增强类的增强方法上明确增强注解,说明该增强方法所能织入的切入点,及在切入点上的位置(前置、后置、环绕、异常)
在这里插入图片描述

四、在xml文件中,动态创建代理对象

在SpringAOP容器中,通过包扫描已将目标对象(被代理对象)和增强类实例(Aspect)在AOP容器中进行生成,所以需要通过一个后置处理器以这个目标对象为结构,动态的创建一个代理类实例,在xml简化的配置可以使用一行代友来实现:

    <!-- TODO:自动成生代理代,采取的仍然是后置处理器,通过getBean()方法获得代理类实例所用的ID仍然是:目标对象用注解定义的ID -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

五、理解后置处理器是如何动态创建代理类

在xml中,通过aop:aspectj-autoproxy,可以在AOP容器中自加载一个后置处理器,通过这个后置处理器,调用指定的动态代理创建技术(JDK技术和CGLIB技术)JDK技术适用于接口实现类,而CGLIB技术更适用于非接口实现类(变通类)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值