Spring AOP的五种通知类型

本文详细介绍了Spring AOP中的五种通知类型:BeforeAdvice、AfterReturningAdvice、AfterThrowingAdvice、AfterAdvice和AroundAdvice,并通过实例展示了它们在切面编程中的应用。此外,还讲解了环绕通知的概念,使用 ProceedingJoinPoint 控制目标方法执行并进行性能筛查。最后,提到了引介增强这一特殊的通知方式,它可以为目标类动态添加属性和方法,改变类的行为。

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

一、五种通知类型

  • 通知是指在什么时机执行切面的方法
注解说明
Before Advice前置通知,目标方法执行运行
After Returning Advice返回后通知,目标方法返回数据后执行
After Throwing Advice异常通知,目标方法抛出异常后执行
After Advice后置通知,目标方法运行后执行
Around Advice环绕通知,最强大的通知,自定义通知执行时机,可决定目标方法是否运行
<aop:config>

<aop:pointcut id="pointcut" expression="execution(* com.learn..*Service.*(..))"></aop:pointcut>

<!--定义切面类-->
<aop:aspect ref="methodAspect">
<!--before-前置通知,目标方法运行前执行methodAspect.printExecutionTime-->
<aop:before method="printExecutionTime" pointcut-ref="pointcut"/>
<!--after-后置通知,目标方法运行后执行doAfter-->
<aop:after method="doAfter" pointcut-ref="pointcut"/>
<!--after returning-返回后通知,目标方法返回数据后执行 -->
<aop:after-returning method="doAfterReturning" returning="ret" pointcut-ref="pointcut"/>
<!--after throwing-异常通知,目标方法抛出异常后执行-->
<aop:after-throwing method="doAfterThrowing" throwing="th" pointcut-ref="pointcut"></aop:after-throwing>
</aop:aspect>
</aop:config>

package com.learn.spring.aop.aspect;


import org.aspectj.lang.JoinPoint;

import java.text.SimpleDateFormat;
import java.util.Date;

// 切面类
public class MethodAspect {
    // 切面方法,用于扩展额外功能
    //JoinPoint连接点,通过连接点可以获取目标类/方法的信息
    public void printExecutionTime(JoinPoint joinPoint){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        String now = sdf.format(new Date());
        String className = joinPoint.getTarget().getClass().getName();// 获取目标类的名称
        String methodName =  joinPoint.getSignature().getName(); //获取目标方法名称
        System.out.println("------>" + now + ":" + className + "." + methodName);
        Object[] args = joinPoint.getArgs();
        System.out.println("----->参数个数:" + args.length);
        for (Object arg : args){
            System.out.println("----->参数:" + arg);
        }
    }

    // 后置通知
    public void doAfter(JoinPoint joinPoint){
        System.out.println("<-----触发后置通知");
    }
    
    //异常通知
    public void doAfterThrowing(JoinPoint joinPoint, Throwable th){
        System.out.println("<-------异常通知:" + th.getMessage());
    }

    // 返回后通知
    public void doAfterReturning(JoinPoint joinPoint, Object ret){
        System.out.println("<----返回后通知:" + ret);
    }
}

二、环绕通知

1.利用AOP进行方法性能筛查
   <bean id="userDao" class="com.learn.spring.aop.dao.UserDao"/>
        <bean id="employeeDao" class="com.learn.spring.aop.dao.EmployeeDao"/>
    <bean id="userService" class="com.learn.spring.aop.service.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>
    <bean id="employeeService" class="com.learn.spring.aop.service.EmployeeService">
        <property name="employeeDao" ref="employeeDao"/>
    </bean>

    <bean id="methodChecker" class="com.learn.spring.aop.aspect.MethodChecker"></bean>
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* com.learn..*.*(..))"></aop:pointcut>
        <aop:aspect ref="methodChecker">
            <!--环绕通知-->
            <aop:around method="check" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>
  • 环绕通知核心方法:proceed()
package com.learn.spring.aop.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MethodChecker {
    // ProceedingJoinPoint时JoinPoint的升级版,在原有的功能外,还可以控制目标方法是否执行
    public Object check(ProceedingJoinPoint pjp) throws Throwable {
        try {
            long startTime = new Date().getTime();
            Object ret = pjp.proceed(); //执行目标方法
            long endTime = new Date().getTime();
            long duration = endTime - startTime; //执行时长
            if (duration >= 1000){
                String className = pjp.getTarget().getClass().getName();
                String methodName = pjp.getSignature().getName();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
                String now = sdf.format(new Date());
                System.out.println("========" + now + ":" + className + "." + methodName + "(" + duration + "ms)===========");
            }
            return  ret;
        } catch (Throwable e) {
           throw e;
        }
    }
}

三、特殊的“通知”- 引介增强

1.什么是引介增强?
  • 引介增强(IntroductionInterceptor)是对类的增加,而非方法
  • 引介增强允许在运行时为目标类增加新属性或方法
  • 引介增强允许在运行时改变类的行为,让类随运行环境动态变更
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值