AOP, Spring 4 MVC и @Around аннотации

#java #spring #spring-mvc #spring-aop

#java #весна #spring-mvc #spring-aop

Вопрос:

Сегодня я пытаюсь управлять некоторыми материалами AOP с помощью Spring 4, и у меня проблема с @Around аннотацией. Он работает только после pointcut и ведет себя как @After аннотации. Что еще хуже — комбинация @Before и @Around аннотации влияет только на вызов метода после pointcut .

Комбинация @After и @Before работает нормально. Честно говоря, я понятия не имею, почему это так работает.

Я также пытаюсь использовать какой-то mockito для обнаружения вызова метода AOP, но он не работает.

У меня есть класс конфигурации

 @Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "my.package.to.aop" })
public class AOPConfiguration {}
  

Класс AOP:

 @Aspect
@Component
public class SmartLoggerAspect {

    @After("execution(* my.package.to.specific.function."
              "repositories.PagingAndSortingBookRepository.findAll("
              "org.springframework.data.domain.Pageable)  )")
    public void afterPage(JoinPoint joinPoint){
        System.out.println("nnnnCALLED AFTER: "   joinPoint.getSignature().getName());
    }

    @Before("execution(* my.package.to.specific.function."
              "repositories.PagingAndSortingBookRepository.findAll("
              "org.springframework.data.domain.Pageable)  )")
    public void beforePage(JoinPoint joinPoint){
        System.out.println("nnnnCALLED BEFORE: "   joinPoint.getSignature().getName());
    }

    @Around("execution(* my.package.to.specific.function."
              "repositories.PagingAndSortingBookRepository.findAll("
              "org.springframework.data.domain.Pageable)  )")
    public void aroundPage(JoinPoint joinPoint){
        System.out.println("nnnnCALLED AROUND: "     joinPoint.getSignature().getName());
    }
}
  

И я сделал для этого unitTest

 @RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { JPAConfig.class, AOPConfiguration.class })
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class })
public class AspectTest {

    @Autowired
    PagingAndSortingBookRepository pagingAndSortingRepo;
    @Autowired
    SmartLoggerAspect smartLoggerAspect;

    JoinPoint joinPoint;


    @Test
    public void pagingTest(){
        pagingAndSortingRepo.findAll(new PageRequest(1, 1));
        //verify(smartLoggerAspect, times(1)).afterPage(joinPoint);
    }
}
  

Комментарии:

1.Зачем вам нужны @Before @After и @Around советы тоже? Почему бы вам не попробовать объединить советы в одном @Around совете?

2. Потому что я новичок и пробую много способов использования AOP. Когда я комментирую функции aBefore и aAfter и оставляю только aAround, у меня все равно возникает та же проблема

3. Что вы имеете в виду, говоря «Это работает только после обрезки точки […]»?

4. Это означает, что сообщение отображается только после вызова метода, а не до (как в документации spring).

Ответ №1:

Я думаю, что проблема заключается в использовании JoinPoint вместо ProceedindJoinPoint метода around рекомендаций.

Также вам необходимо вызвать pjp.proceed метод в советах around.

Цитирование из spring docs

Первый параметр метода advice должен иметь тип ProceedingJoinPoint . В теле рекомендации вызов proceed() в ProceduingJoinPoint вызывает выполнение базового метода.

Комментарии:

1. Нет, я отредактировал эту функцию @Around(«выполнение (* my.package.to.specific.function». «репозитории. Разбиение на страницы и сортировкаbookrepository.findAll(» «org.springframework.data.domain. Доступная для просмотра) )») общедоступная пустота вокруг страницы (ProceedingJoinPoint ProceedingJoinPoint) выдает Throwable{ ProceedingJoinPoint.proceed(); System.out.println(«n n n nCALLED AROUND: » ProceedingJoinPoint.getSignature().getName()); } И по-прежнему возникает та же проблема