Spring Aop--通知注解

一、环绕注解

环绕注解

环绕注解@Aroud

注解 描述
@Around @Around是Spring AOP中的一种通知类型,用于在目标方法执行前后进行环绕操作。它可以在方法调用前后增加额外的逻辑,例如日志记录、性能监控等。@Around注解需要配合AspectJ表达式来指定切入点,定义切面类的方法,并在方法内部通过ProceedingJoinPoint参数来控制目标方法的执行流程。

环绕注解,通过环绕注解可以实现对增强的整合。

对于环绕注解需要创建ProceedingJoinPoint对象并需要使用连两个对应方法

方法 描述
proceed() 执行被通知的目标方法,并返回其返回值。在环绕通知中必须调用此方法,否则目标方法不会执行。
getArgs() 获取目标方法的参数值数组。返回的参数数组是Object类型的。

环绕注解使用案例:

java 复制代码
@Component
@Aspect
public class RoundAdvice {

    @Around("com.alphamilk.Advice.MyPointcut.pointcut1()")
    public Object Transation(ProceedingJoinPoint joinPoint){
//        获取方法参数
        Object[] args = joinPoint.getArgs();
//        获取返回值
        Object result = null;

        try {
            System.out.println("事务开始");
//            执行对应方法
           result =  joinPoint.proceed(args);
            System.out.println("事务结束");
        } catch (Throwable e) {
            System.out.println("事务回滚");
            throw new RuntimeException(e);
        }
        return result;
    }
}

注意:使用增强需要开启通知注解

java 复制代码
@ComponentScan(value = "com.alphamilk")
@Configuration
//开启增强注解
@EnableAspectJAutoProxy
public class JavaConfig {
}

而如果不是使用环绕注解,则需要使用@Before @After @AfterReturning等

java 复制代码
@Component
@Aspect
public class advice {
  @Before("com.alphamilk.Advice.MyPointcut.pointcut1()")
    public void Before(JoinPoint joinPoint) {
        System.out.println("事务开始");
    }

 @After("com.alphamilk.Advice.MyPointcut.pointcut1()")
    public void After(JoinPoint joinPoint) {
        System.out.println("事务结束");
    }

    @AfterReturning(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",returning = "result")
    public void AfterReturning(JoinPoint joinPoint,Object result) {
        System.out.println("调用拥有返回值的方法");
    }

    @AfterThrowing(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",throwing = "throwable")
    public void AfterThrowing(JoinPoint joinPoint,Throwable throwable) {
        System.out.println("调用有异常的方法");
    }
}

使用环绕注解的优缺点

优点:

  1. 灵活性高:环绕注解提供了最大程度的灵活性,可以在目标方法执行前后插入额外的逻辑代码,对方法的执行过程进行全面控制。
  2. 统一处理:通过环绕注解,可以将通用的逻辑代码抽取到切面中,实现统一的处理逻辑,避免在各个目标方法中重复编写相同的代码。
  3. 可以修改返回值:在环绕通知中,可以通过修改目标方法的返回值来影响最终的结果。

缺点:

  1. 复杂性增加:相对于其他类型的通知,环绕注解的使用稍显复杂,需要更多的理解和掌握,特别是对于ProceedingJoinPoint的使用。
  2. 性能开销:由于环绕注解会包裹整个目标方法的执行流程,在某些情况下可能会带来一定的性能开销,特别是处理逻辑较为复杂的情况。
  3. 可能引入副作用:在环绕通知中对目标方法做任意修改时,需要谨慎操作,避免引入不可预料的副作用,导致程序出现异常或不正常的行为。

二、优先级注解

注解 描述
@Order @Order是Spring框架中用于定义组件的加载顺序的注解。它可以用在类级别或方法级别上。当多个组件都实现了同一个接口或继承了同一个父类时,通过@Order注解可以指定它们的加载顺序。@Order的值越小,优先级越高,具有更高的加载顺序。@Order注解的值可以是任意整数。需要注意的是,相同优先级的组件加载顺序是不确定的,所以最好将优先级设置为不同的值来避免不确定性。

如果对于同一个方法有两种甚至多种增强,并且需要指定增强的循序,则需要使用@Order优先级注解来设置。

对于其使用,核心在于:指定一个优先级,Order的值越低越是优先,越高优先级前置先执行,后置后执行

案例代码:(第一个增强)

java 复制代码
@Component
@Aspect
//设置一个优先级更高注解
@Order(10)
public class advice {
  @Before("com.alphamilk.Advice.MyPointcut.pointcut1()")
    public void Before(JoinPoint joinPoint) {
        System.out.println("优先级高前置执行");
    }

 @After("com.alphamilk.Advice.MyPointcut.pointcut1()")
    public void After(JoinPoint joinPoint) {
        System.out.println("优先级高后置后执行");
    }

    @AfterReturning(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",returning = "result")
    public void AfterReturning(JoinPoint joinPoint,Object result) {
        System.out.println("调用拥有返回值的方法");
    }

    @AfterThrowing(value = "com.alphamilk.Advice.MyPointcut.pointcut1()",throwing = "throwable")
    public void AfterThrowing(JoinPoint joinPoint,Throwable throwable) {
        System.out.println("调用有异常的方法");
    }
}

第二个增强

java 复制代码
@Component
@Aspect
@Order(20)
public class RoundAdvice {

    @Around("com.alphamilk.Advice.MyPointcut.pointcut1()")

    public Object Transation(ProceedingJoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        Object result = null;

        try {
            System.out.println("优先级低前置后执行");
//            执行对应方法
           result =  joinPoint.proceed(args);
            System.out.println("优先级低后置先执行");
        } catch (Throwable e) {
            System.out.println("事务回滚");
            throw new RuntimeException(e);
        }
        return result;
    }
}

相关推荐
Bs_MoneyMagnet3 小时前
基于springboot+vue的心理咨询预约与随访平台的设计与实现 源码+文档
vue.js·spring boot·后端·spring·毕业设计·旅游·计算机毕业设计
步行cgn8 小时前
Spring 底层如何创建对象:反射机制与实例化策略
java·后端·spring
步行cgn10 小时前
Spring 注入 null 和空字符串详解
数据库·spring·oracle
Wang's Blog11 小时前
Java框架快速入门: Spring Security+OAuth2之单点登录(SSO)实战
服务器·spring·状态模式
譕痕11 小时前
Idea 集成 智能体开发工具“千问(qwen)”
java·ide·spring·语言模型
步行cgn12 小时前
Spring 注入内部 Bean 详解
java·spring·rpc
前端初见13 小时前
Java+AI零基础入门到大牛
java·spring boot·spring·java-ee·intellij-idea
天天喝旺仔13 小时前
深入理解 JWT:从 Token 结构、签名机制到前后端鉴权实战
redis·安全·spring·微服务·https
QQ_216962909614 小时前
基于SpringBoot+Vue的小生活平台的设计与实现
java·数据库·vue.js·spring boot·spring·微信小程序·生活
yxlalm14 小时前
SpringAI+RAG-检索文档变知识:从上传到精准检索的完整链路
spring·知识库·rag