【发布时间】:2021-09-10 17:13:24
【问题描述】:
我的使用 ACL 的 Java Spring 应用程序有一个服务方法来检索与给定用户对应的所有对象:
@Override
@PostFilter("hasPermission(filterObject, 'READ') or hasPermission(filterObject, 'ADMINISTRATION')")
public List<SomeClass> findAll() {
return SomeClassRepository.findAll();
}
不幸的是,在数据库中有很多对象的情况下,这种方法需要很长时间才能完成(超过 1 秒)。可能是因为它会先从数据库中取出所有的对象,然后在内存中一一过滤。如何在不失去 Spring ACL 优势的情况下对其进行优化?
编辑:我现在想出的解决方案是为 acl_sid 和 acl_entry 存储库创建存储库,并通过这些存储库获取感兴趣对象的 ID。与上述方法相比,这使我的执行时间提高了 10 倍。新代码如下所示:
@Override
@PostFilter("hasPermission(filterObject, 'READ') or hasPermission(filterObject, 'ADMINISTRATION')")
public List<SomeClass> findAll() {
List<SomeClass> result = new ArrayList<SomeClass>();
Long userId = (Long) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
AclSid sid = aclSidRepository.findBySid(Long.toString(userId));
List<AclEntry> aclEntries = aclEntryRepository.findBySid(sid);
for (AclEntry aclEntry : aclEntries) {
AclObjectIdentity aclObjectIdentity = aclEntry.getAclObjectIdentity();
AclClass aclClass = aclObjectIdentity.getObjectIdClass();
if (aclClass.getClassName().equals("com.company.app.entity.SomeClass")) {
Optional<SomeClass> SomeClass = SomeClassRepository
.findById(aclObjectIdentity.getObjectIdIdentity());
if (SomeClass.isPresent()) {
result.add(SomeClass.get());
}
}
}
return result;
}
【问题讨论】:
-
这些对象多久更改一次?
-
@SimonMartinelli 这些是用户可编辑的对象,因此可以随时更改
-
您可能需要在存储库中移动 hasPermission(...) 以对其进行优化,如果有帮助,请查看此内容:stackoverflow.com/questions/49058363/…
-
并在将权限检查条件移入查询时使用存储库中的 Pageable 方法
标签: java spring spring-boot spring-security