如何在Spring Data REST服务器内部通过Self Link加载实体?
在Spring Data REST内部通过Self Link加载实体
问题背景
基于Spring Boot Gradle Plugin 2.2.5.RELEASE构建的SDR服务器,希望在应用内部通过实体的Self Link直接加载对应的@Entity对象,而不是通过外部HTTP客户端调用。
解决方案:用SDR标准组件实现
当然可以实现!Spring Data REST(SDR)本身就提供了一套标准机制,让你在服务器内部直接通过Self Link加载实体,完全不用绕HTTP调用。下面是完整的实现代码,完全基于SDR原生组件:
import org.springframework.context.ApplicationContext; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.support.RepositoryFactorySupport; import org.springframework.data.rest.core.EntityLinks; import org.springframework.hateoas.Link; import org.springframework.stereotype.Service; import java.io.Serializable; import java.util.Objects; import java.util.Optional; @Service public class SelfLinkResolver { private final EntityLinks entityLinks; private final ApplicationContext applicationContext; // 注入SDR核心组件EntityLinks和Spring上下文 public SelfLinkResolver(EntityLinks entityLinks, ApplicationContext applicationContext) { this.entityLinks = entityLinks; this.applicationContext = applicationContext; } @SuppressWarnings("unchecked") public <T> T findBySelfLink(Link self) { // 参数校验:确保传入的是有效的Self Link if (self == null || !Link.REL_SELF.equals(self.getRel())) { throw new IllegalArgumentException("必须传入有效的Self Link"); } // 解析Link对应的实体元数据PersistentEntity Optional<PersistentEntity<?, ?>> persistentEntity = entityLinks.getPersistentEntity(self); if (persistentEntity.isEmpty()) { throw new IllegalArgumentException("无法找到该Link对应的实体类型: " + self); } Class<?> entityType = persistentEntity.get().getType(); // 获取该实体对应的CrudRepository(如果用JpaRepository可以替换成对应的接口) CrudRepository<?, ?> repository = applicationContext.getBean( RepositoryFactorySupport.getRepositoryInterface(entityType, CrudRepository.class) ); // 从Link中自动提取实体ID,无需手动解析URL Object id = entityLinks.extractIdFromLink(self); // 通过Repository加载实体,找不到则抛出异常(也可以返回Optional) return (T) repository.findById((Serializable) id) .orElseThrow(() -> new RuntimeException("未找到Self Link对应的实体: " + self)); } public void exampleCall() { // 注意:推荐用SDR生成的标准Link,避免硬编码路径(这里是示例) // 实际场景中,这个Link可能来自SDR返回的资源对象(比如PersistentEntityResource) Link selfLink = new Link("/users/1"); User user = findBySelfLink(selfLink); Objects.requireNonNull(user, "加载实体失败"); // 后续可以对user做业务处理 } }
关键细节说明
EntityLinks的作用:这是SDR的核心工具类,负责解析Link对应的实体元数据,以及从Link中提取实体ID,完全封装了URL解析的逻辑,不用自己处理路径规则。- Repository的获取:通过
ApplicationContext根据实体类型获取对应的Repository Bean,确保使用的是SDR管理的标准Repository。 - 路径注意事项:传入的Link建议使用SDR生成的相对路径(比如
/users/1),如果是绝对URL,EntityLinks也能正确解析,但相对路径更简洁可靠。 - 异常处理:示例中用了抛出异常的方式,你可以根据业务需求改成返回
Optional<T>,让调用方自行处理空值情况。
内容的提问来源于stack exchange,提问作者dcio
相关产品推荐
相关产品推荐

