首页 > 解决方案 > 为什么 Spring-AOP 切入点适用于 save(..) 而不是 saveAll(..)

问题描述

我有一个这样的 Spring-Data 存储库:

package com.example.demo;

@RepositoryRestResource
public interface FooRepository extends JpaRepository<Foo, Long> {

    @Override
    <S extends Foo> S save(S entity);

    @Override
    <S extends Foo> List<S> saveAll(Iterable<S> entities);

}

像这样的一个方面:

@Aspect
@Component
public class FooAspect {

    @Before("execution(* org.springframework.data.repository.CrudRepository.save(*))")
    void crudSaveBefore(JoinPoint joinPoint) throws Throwable {
        System.out.println("crud save");
    }

    @Before("execution(* com.example.demo.FooRepository.save(*))")
    void fooSaveBefore(JoinPoint joinPoint) throws Throwable {
        System.out.println("foo save");
    }

    @Before("execution(* org.springframework.data.repository.CrudRepository.saveAll(*))")
    void crudSaveAll(JoinPoint joinPoint) throws Throwable {
        System.out.println("crud save all");
    }

    @Before("execution(* com.example.demo.FooRepository.saveAll(*))")
    void fooSaveAll(JoinPoint joinPoint) throws Throwable {
        System.out.println("foo save all");
    }

}

当我运行fooRepository.save(..)时,在控制台中我看到:foo save

当我运行fooRepository.saveAll(..)时,在控制台中我看到foo save all并且crud save all

我希望saveAll只截取FooRepository风味,因为我直接切入 package.class.method。这似乎奏效了save,但不是saveAll

这是因为 argssaveAllIterable?还是泛型在这里发生某种类型的擦除?还有什么?

标签: javaspring-bootaopspring-aoppointcut

解决方案


似乎是 AOP 问题。对于代理FooRepository.saveAll,它调用CrudRepository.saveAll @Before表达式:

AbstractAspectJAdvice 683 AOP 切入点


推荐阅读