Spring AOP работает в почтительном порядке - PullRequest
0 голосов
/ 30 марта 2020

Я сейчас испытываю что-то довольно странное. Я должен Aspect классы, оба они имеют один и тот же pointcut в теге AfterThrowing. Классы Aspect упорядочены, но всегда запускается первый класс с более низким приоритетом, что, по моему мнению, является противоположностью ожидаемого поведения.

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect
@Order(1)
public class AspectOne {

@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
    System.out.println("AspectOne");
}

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Aspect
@Order(2)
public class AspectTwo {

@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
    System.out.println("AspectTwo");
}

Согласно документации, чем меньше число есть, чем выше присутствие. Тем не менее, мой вывод:

  • AspectTwo
  • AspectOne

Если я переключу порядок, результат также изменится. Таким образом, Орден работает, но все наоборот. Я пробовал с разными номерами, результаты совпадают.

1 Ответ

2 голосов
/ 30 марта 2020

Порядок работает на аспект и работает как надо. Однако последующие советы выполняются в обратном порядке.

Представьте, что ваши аспекты имеют как @Before, так и @After

@Component
@Aspect
@Order(1)
public class AspectOne {

@Before(pointcut = "exection(* com.test.*..*(..))")
public void soSomethingBefore(Joinpoint jp) {
    System.out.println("[BEFORE] AspectOne");
}

@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
    System.out.println("[AFTER ] AspectOne");
}

и

@Component
@Aspect
@Order(2)
public class AspectTwo {

@Before(pointcut = "exection(* com.test.*..*(..))")
public void soSomethingBefore(Joinpoint jp) {
    System.out.println("[BEFORE] AspectTwo");
}

@AfterThrowing(pointcut = "exection(* com.test.*..*(..))", throwing = "ex")
public void doSomething(JoinPoint jp, Exception ex){
    System.out.println("[AFTER ] AspectTwo");
}

Если вы посмотрите на результат, он будет

[BEFORE] AspectOne
[BEFORE] AspectTwo
[AFTER ] AspectTwo
[AFTER ] AspeectOne

Таким образом, оформление заказа выполнено, однако вы должны принять во внимание, что после того, как советы будут в обратном порядке.

Вы можете спросить, почему?

Давайте посмотрим @Around совет, который в основном является @Before и @After советом. Если первый аспект касается запуска транзакции, это должен быть последний для фиксации / отката транзакции, поскольку все промежуточное должно участвовать в одной транзакции. Если бы он был первым, кто запустил и зафиксировал другие части выполнения, он не был бы частью tx, что может привести к странным проблемам.

ПРИМЕЧАНИЕ: Удалите @Configuration и @EnableAspectJAutoProxy, просто создайте 1 класс конфигурации, который делает это, и сделайте ваши аспекты регулярными @Component классами.

...