我有一个授权类(Spring @Component
),它的方法将实体作为参数,并检查当前用户是否具有访问它的必要权限。
首先,我注解了控制器的方法来检查权限:
@PreAuthorize("@authorizationComponent.hasPermission(@myService.findById(#entityId))")
这使得 * 成为对数据库的初始查询 *,以通过findById
检索实体。
然后,我想再次检索方法体中的实体来执行我的路由逻辑:
// can be inside a service method
MyEntity entity = this.myService.findById(entityId)
这将向数据库发出***第二个请求***。
**这是使用Spring的正确方法吗?**例如,我知道我可以在我的授权组件中创建一个方法,该方法将返回加载的实体,然后我可以调用该方法,但这真的是要走的路吗?
我对我的授权有复杂的要求,有时我不得不检查实体是否由用户对其拥有权利的某种关系所拥有。这可能很快变得复杂。
1条答案
按热度按时间vm0i2vca1#
假设你使用的是JPA,你可以确保
@Transactional
在@PreAuthorize
之前执行,这样业务服务方法和@PreAuthorize
方法都在同一个事务中运行,因为JPA会将通过Id获取的实体缓存到同一个事务的一级缓存中。这意味着在
@PreAuthorize
方法中,它从DB获取实体,然后将其放入第一级缓存中。然后在业务方法的后面,它将检查第一级缓存是否包含具有相同ID的实体。如果是的话,它会得到它,而不会击中DB。您可以配置
@Transactional
和@PreAuthorize
到@EnableTransactionManagement
和@EnableGlobalMethodSecurity
的执行顺序,如下所示:我猜较小的订单值将首先执行,但我让你来确认。