首页 > 解决方案 > Spring AOP 忽略 JPA 的 repository 方法注解

问题描述

我有一个使用 Spring Data REST、Spring JPA、Hibernate 的 Spring Boot 2.3 项目。

我有一个像这样的方面,它将 Hibernate 过滤器应用于我的所有查询:

@Aspect
@Order(1)
@Component
@Log4j2
public class PortalSecurityAspect {

    @Pointcut("!@annotation(com.server.aop.ExcludePortalSecurityCheck) && execution(public * javax.persistence.EntityManager+.*Query(..))")
    private void createQuery() {
    }

    @Around(value = "createQuery() && target(entityManager)")
    public Object applyFilter(ProceedingJoinPoint pjp, Object entityManager) throws Throwable {
        try {
            if (SecurityUtils.getLoggedRoles().contains(Role.ROLE_CUSTOMER)) {
                if (SecurityUtils.getLoggedId() != null) {
                    ((EntityManager) entityManager).unwrap(Session.class).enableFilter("customerFilter").setParameter("contactId", SecurityUtils.getLoggedId());
                    log.trace(">>>>Enabling filter customer {}", SecurityUtils.getLoggedUser().getSid());
                } else {
                    ((EntityManager) entityManager).unwrap(Session.class).enableFilter("customerFilter").setParameter("contactId", -1l);
                    log.warn("Logged ID is null. Customer filter cannot be applied");
                }
            }
        } catch (Exception e) {
            log.warn("Unable to enable filter");
        }
        return pjp.proceed();
    }

}

我有一些这样的 JPA 存储库:

@Transactional
@PreAuthorize("isAuthenticated()")
public interface DocumentRepository extends JpaRepository<Document, Long>, DocumentCustomRepository<Document, Long>, JpaSpecificationExecutor<Document> {


    @ExcludePortalSecurityCheck
    @Cacheable(cacheNames = "documents#chartpopulartimes")
    @Transactional(readOnly = true)
    @Query("SELECT etc etc etc etc")
    List<Object[]> chartPopularTimes(@Param("from") Instant from, @Param("until") Instant until, @Nullable @Param("storeId") Long storeId);

我希望将 hibernate 过滤器添加到一些使用我的自定义注释注释的特殊方法中@ExcludePortalSecurityCheck

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExcludePortalSecurityCheck {
}

正如您在 Aspect Pointcut 中看到的那样,我 !@annotation(com.server.aop.ExcludePortalSecurityCheck)在 AND 中定义了一个条件集。但是,即使我调用该方法,也PortalSecurityAspect可以随时应用过滤器。可能切入点应用于没有该注释的 Spring 类方法。你有什么建议吗?

标签: javaspringspring-data-jpaspring-aopspring-data-rest

解决方案


推荐阅读