AOP切面的优先级Order属性

欣喜 Spring 发布时间:2025-03-19 09:44:25 阅读数:12039 1
下文笔者讲述AOP的order属性的简介说明,如下所示

order属性简介

在使用面向切面编程(AOP)时
 切面(Aspect)优先级是一个重要的概念
  特别是在多个切面同时作用于同一个连接点(Join Point)时
  通过设置切面的优先级
   可以控制切面的执行顺序。。
Aop中order注解的功能:
    在Spring AOP中
	  可以使用`@Order`注解来指定切面的优先级

`@Order`注解

`@Order`注解的功能:
   用于指定切面的优先级
   值越小,优先级越高
   值越小,这个切面越会在前面运行

常见的order语法

import org.springframework.core.annotation.Order;

@Aspect
@Order(value)
public class MyAspect {
    // 切面方法
}
 
- `value`:
  一个整数值
  表示切面的优先级
  值越小,优先级越高
有两个切面 `LoggingAspect` 和 `SecurityAspect`
 您希望 `SecurityAspect` 在 `LoggingAspect` 之前执行
 则采用以下方式定义和处理

1.定义 `LoggingAspect`

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(2) // 优先级较低
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("LoggingAspect: Before method " + joinPoint.getSignature().getName());
    }
}

2.定义 `SecurityAspect`

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(1) // 优先级较高
@Component
public class SecurityAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void checkSecurity(JoinPoint joinPoint) {
        System.out.println("SecurityAspect: Checking security for method " + joinPoint.getSignature().getName());
    }
}

执行顺序

-`SecurityAspect`:
   由于 `@Order(1)`,优先级较高,
     会在 `LoggingAspect` 之前执行。
- `LoggingAspect`:
   由于 `@Order(2)`,优先级较低,
     会在 `SecurityAspect` 之后执行。

完整示例

1.定义`LoggingAspect`

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(2) // 优先级较低
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("LoggingAspect: Before method " + joinPoint.getSignature().getName());
    }
}

2.定义`SecurityAspect`

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Order(1) // 优先级较高
@Component
public class SecurityAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void checkSecurity(JoinPoint joinPoint) {
        System.out.println("SecurityAspect: Checking security for method " + joinPoint.getSignature().getName());
    }
}

3.配置 Spring 应用上下文
  确保在 Spring 应用上下文中启用 AOP 支持。
  可以通过 XML 配置或 Java 配置来实现。

Java 配置示例:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
}
```


**XML 配置示例:**

<aop:aspectj-autoproxy />

<context:component-scan base-package="com.example" />

4.定义服务类

package com.example.service;

import org.springframework.stereotype.Service;

@Service
public class MyService {

    public void performAction() {
        System.out.println("MyService: Performing action");
    }
}

5.测试切面

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        MyService myService = context.getBean(MyService.class);
        myService.performAction();
    }
}
输出 
SecurityAspect: Checking security for method performAction
LoggingAspect: Before method performAction
MyService: Performing action

APO之order注意事项

1.优先级值:
   - 使用整数值来指定优先级,值越小,优先级越高。
   - 如果不指定 `@Order` 注解,
      默认优先级为 `Integer.MAX_VALUE`,即最低优先级。

2.多个切面:
   - 如果有多个切面需要排序,
     确保每个切面的 `@Order` 值不同,
	   以便明确排序顺序。

3.切点表达式:
   - 确保切点表达式正确,
     以便切面能够正确地拦截目标方法。

4. 性能考虑:
   - 设置合理的优先级,
     避免不必要的性能开销。
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/Spring/202503/8376.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者