spring四大通知与环绕通知的配置一篇文章带你快速了解

先写一个模拟日志通知的Logger类并配置相应的注解标签

@Component("logger")//把logger类交给spring
@Aspect//表示当前是一个切面类
public class Logger {
    @Before("execution(* com.lwh.service.impl.UserServiceImpl.*(..))")
    public void printLog(){
        System.out.println("前置通知日志打印了");
    }
    @AfterReturning("execution(* com.lwh.service.impl.UserServiceImpl.*(..))")
    public void afterReturnPrint(){
        System.out.println("后置通知打印了");
    }
    @AfterThrowing("execution(* com.lwh.service.impl.UserServiceImpl.*(..))")
    public void afterThrowingPrint(){
        System.out.println("异常通知打印了");
    }
    @After("execution(* com.lwh.service.impl.UserServiceImpl.*(..))")
    public void afterPrint(){
        System.out.println("最终通知打印了");
    }

然后在bean.xml配置相应的注解

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
       <context:component-scan base-package="com.lwh"></context:component-scan>//扫描包
       <aop:aspectj-autoproxy></aop:aspectj-autoproxy>//自动完成创建代理织入切面的工作
</beans>

这样就完成了注解的四大通知的配置,接下来看看环绕通知的配置

首先要在bean.xml加上如下

<aop:config>
    <aop:pointcut id="pt1" expression="execution(* com.lwh.service.impl.*.*(..))"/>
    <aop:aspect id="logAdvice" ref="logger">
        <aop:around method="arroundPrintLog" pointcut-ref="pt1"></aop:around>
    </aop:aspect>
</aop:config>

然后在logger类中加上如下

public Object arroundPrintLog(ProceedingJoinPoint pjp){
    Object rtValue=null;
    try {
        Object[] args=pjp.getArgs();
        System.out.println("环绕前置通知开始打印");//以pjp.proceed为参照物
        rtValue=pjp.proceed(args);   //明确调用业务层方法:切入点方法
        System.out.println("环绕后置置通知开始打印");
        return rtValue;
    }catch (Throwable e)
    {    //catch表示异常通知
        System.out.println("环绕异常通知开始打印");
        throw new RuntimeException(e);
    }
    finally {//finall表示最终通知
        System.out.println("环绕最终通知开始打印");
    }

}

tips:

问题:当有环绕通知的时候 切入点方法就不会执行了 而前置通知还可以执行
分析:通过对比动态代理的环绕通知代码 发现动态代理有明确的切入点方法调用 而我们的代码中没有
解决:spring框架为我们提供了一个借口,ProceedingJoinPoint 该借口有一个方法proceed() 此方法就相当于明确调用切入点的方法 该接口可以作为环绕通知的方法参数 在程序执行时 spring会为我们提供该接口的实现类供我们使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值