java Spring数据JpaRepository。保存*(…)建议行不通
我有一个Spring Boot应用程序,我还扩展了一个JpaRepository:
public interface BusinessRelationshipRepository
extends JpaRepository<BusinessRelationshipEntity, String>,
RevisionRepository<BusinessRelationshipEntity, String, Long> {
// ...
}
此外,我还通过几种建议方法实现了一个方面:
@Aspect
@Log
@Component
class BusinessRelationshipAspect {
private final BusinessRelationshipRepository relationshipRepository;
@PersistenceContext
private EntityManager entityManager;
@Autowired
public BusinessRelationshipAspect(
final BusinessRelationshipRepository relationshipRepository) {
this.relationshipRepository = relationshipRepository;
log.severe("The Aspect was created");
}
/**
* The advice pointcut definition is based on the BusinessRelationshipRepository.
*/
@Around(
"execution(* *.BusinessRelationshipRepository"
+ ".save*(..))")
public Object onBusinessRelationshipSaveAll(final ProceedingJoinPoint joinPoint)
throws Throwable {
// ...
sendChangeMessage(var1, var2);
return relationshipsAfter;
}
/**
* The advice pointcut definition is based on the BusinessRelationshipRepository.
*/
@Around(
"execution(* *.BusinessRelationshipRepository"
+ ".deleteAll(..))")
public Object onBusinessRelationshipDeleteAll(final ProceedingJoinPoint joinPoint)
throws Throwable {
// ...
sendChangeMessage(var1, var2);
}
// handles the update, create, archive changes
public void sendChangeMessage(final BusinessRelationshipEntity oldObject,
final BusinessRelationshipEntity newObject) {
// ...
sendJmsMessage(changeMessage);
}
private void sendJmsMessage(final ChangeMessage chgMsg) {
// ...
}
}
我不明白的是,为什么deleteAll
总是被拦截,而saveAll
从来没有被拦截过?
我尝试调试Spring的AOP框架,BusinessRelationshipRepository的JDKDDynamicAOPProxy实例,它显示了以下建议:
org.springframework.aop.framework.ProxyFactory: 5 interfaces [com.company.org.management.persistence.repo.BusinessRelationshipRepository,
org.springframework.data.repository.Repository,
org.springframework.transaction.interceptor.TransactionalProxy,
org.springframework.aop.framework.Advised, org.springframework.core.DecoratingProxy];
3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,
InstantiationModelAwarePointcutAdvisor: expression [execution(* *.BusinessRelationshipRepository.deleteAll(..))]; advice method [public java.lang.Object com.company.org.management.aspect.BusinessRelationshipAspect.onBusinessRelationshipDeleteAll(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable]; perClauseKind=SINGLETON,
InstantiationModelAwarePointcutAdvisor: expression [execution(* *.BusinessRelationshipRepository.save*(..))]; advice method [public java.lang.Object com.company.org.management.aspect.BusinessRelationshipAspect.onBusinessRelationshipSaveAll(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.sun.proxy.$Proxy221@594bedf5]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false
当我截取saveAll方法调用时,在拦截器链中,我找不到上面指定的方法:
更新:
我已经更新了上面的片段。我有一个私有方法(sendJmsMessage
)。。。一旦我放松了能见度,比如对公众,拦截器就开始工作了
我还有另一个独立的方面,几乎相同的定义^{
2021-12-03:
我对上述私有方法的假设是错误的——这种行为是零星的,这让我认为它与Spring AOP在启动期间构建的一些缓存以及创建JDKDynamicAopProxy实例时如何使用这些缓存有关。奇怪的是deleteAll
总是有效的。
我还将代码的简化版本推到了https://github.com/gkgeorgiev/aop-demo。请注意,问题是随机的,您可能需要重新启动应用2-3次
2021-12-06:我创建了一个Spring GitHub问题,以防其他人面临同样的问题https://github.com/spring-projects/spring-framework/issues/27761
共 (0) 个答案