【问题标题】:AOP, Spring 4 MVC and @Around annotationAOP、Spring 4 MVC 和 @Around 注解
【发布时间】:2016-11-02 08:37:59
【问题描述】:

今天我试图用 Spring 4 管理一些 AOP 的东西,我遇到了 @Around 注释的问题。它仅在切入点之后起作用,并且行为类似于 @After 注释。更糟糕的是 - 组合 @Before 和 @Around 注释仅在切入点之后调用方法时起作用。

@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("\n\n\n\nCALLED 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("\n\n\n\nCALLED 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("\n\n\n\nCALLED AROUND: " +   joinPoint.getSignature().getName());
    }
}

我为它做了一个单元测试

@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);
    }
}

【问题讨论】:

  • 为什么你还需要@Before+@After @Around 建议?为什么不尝试将这些建议合并到一个 @Around 建议中?
  • 因为我是一个初学者并且尝试了很多方法来使用AOP。当我评论 aBefore 和 aAfter 函数并只留下 aAround 时,我仍然遇到同样的问题
  • “仅在切入点 [...] 后有效”是什么意思?
  • 这意味着消息仅在调用方法之后显示,而不是之前显示(就像在 spring 文档中一样)。

标签: java spring spring-mvc spring-aop


【解决方案1】:

我认为问题在于 around 建议方法使用 JoinPoint 而不是 ProceedindJoinPoint

您还需要在环绕通知中调用pjp.proceed 方法。

引用spring docs

advice 方法的第一个参数必须是 ProceedingJoinPoint 类型。在通知正文中,对 ProceedingJoinPoint 调用proceed() 会导致底层方法执行。

【讨论】:

  • 不,我编辑了这个函数 @Around("execution(* my.package.to.specific.function." + "repositories.PagingAndSortingBookRepository.findAll(" + "org.springframework.data.domain. Pageable) )") public void aroundPage(ProceedingJoinPointproceedJoinPoint) throws Throwable{proceedingJoinPoint.proceed(); System.out.println("\n\n\n\n调用:" +progressingJoinPoint.getSignature().getName());仍然遇到同样的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 2022-08-20
相关资源
最近更新 更多