[英]Given a Spring Data Rest URI, How Do you find the associated target repository?
I'm building an application using Spring Data REST and implementing an interceptor pattern using a MappedInterceptor
as suggested in this post .我正在使用 Spring Data REST 构建一个应用程序,并按照这篇文章中的建议使用MappedInterceptor
实现拦截器模式。 The interceptor works as expected and it intercepts @RestControllers
.拦截器按预期工作,它拦截@RestControllers
。
Now, using the parameters available in the preHandle(…)
method signature (these include: HttpServletRequest request, HttpServletResponse response, Object handler => can be casted to org.springframework.web.method.HandlerMethod
), how can I access the RestRepository class or repository Method being invoked (the getMethod()
, from the HandlerMethod class, works great with Concrete classes, but it does not work with Repository interfaces, it ends returning a RestAbstractController class that invokes the target repository through reflection)???现在,使用preHandle(…)
方法签名中可用的参数(这些包括: HttpServletRequest request, HttpServletResponse response, Object handler => can be casted to org.springframework.web.method.HandlerMethod
),我如何访问 RestRepository 类或正在调用存储库方法(来自 HandlerMethod 类的getMethod()
与 Concrete 类一起工作很好,但它不适用于 Repository 接口,它结束返回通过反射调用目标存储库的 RestAbstractController 类)???
Why I need this?为什么我需要这个?
Because, I´m doing a cross-cutting logic that needs to access the Repository interface to find a specific business annotation, if the annotation is present, some logic is done (like setting MDC
special values, for example)...因为,我正在做一个横切逻辑,需要访问 Repository 接口来查找特定的业务注释,如果存在注释,则完成一些逻辑(例如设置MDC
特殊值)...
Thanks...谢谢...
The most flexible way to generically lookup and use Spring Data repositories is through the Repositories
and RepositoryInvoker
abstractions.一般查找和使用 Spring Data 存储库的最灵活方法是通过Repositories
和RepositoryInvoker
抽象。 The former provides by-type lookup abilities of metadata about the repositories and the repositories themselves.前者提供有关存储库和存储库本身的元数据的按类型查找功能。 The latter allows generic invocation of CRUD and query methods on those repositories.后者允许在这些存储库上通用调用 CRUD 和查询方法。 This additional abstraction is necessary as Spring Data repositories don't have to implement a special interface as long as they expose methods that are syntactically equivalent to the ones provided in Spring Data's CrudRepository
.这种额外的抽象是必要的,因为 Spring Data 存储库不必实现特殊的接口,只要它们公开的方法在语法上与 Spring Data 的CrudRepository
提供的方法CrudRepository
。
If you know about the actual domain class you're trying to access the repository for you can get an instance of Repositories
injected into your class.如果您知道您尝试访问存储库的实际域类,则可以将Repositories
实例注入到您的类中。 That one in turn allows you to lookup entity and repository information as well as the repository itself.这反过来又允许您查找实体和存储库信息以及存储库本身。
As the latter doesn't have to implement a dedicated interface mandatorily, Repositories.getRepositoryFor(…)
only returns Optional<Object>
which isn't too helpful if you want to actually do stuff on the repository.由于后者不必强制实现专用接口,因此Repositories.getRepositoryFor(…)
仅返回Optional<Object>
如果您想在存储库上实际执行操作,这并没有太大帮助。 RepositoryInvokerFactory
allows you to create RepositoryInvoker
instances that allow you to invoke certain methods on a repository explicitly independent of way they're actually declared. RepositoryInvokerFactory
允许您创建RepositoryInvoker
实例,这些实例允许您显式调用存储库上的某些方法,而与它们实际声明的方式无关。
@Component
@RequiredArgsConstructor
class SomeComponent {
private final Repositories repositories;
public <T> void someMethod(Class<T> type) {
… = repositories.getEntityInformation(type);
RepositoryInvokerFactory factory = new DefaultRepositoryInvokerFactory(repositories);
RepositoryInvoker invoker = factory.getInvokerFor(type);
Optional<T> entity = invoker.invokeFindById(4711);
}
}
Note, that a Repositories
instance is available as Spring Bean if you use Spring Data REST.请注意,如果您使用 Spring Data REST,则Repositories
实例可用作 Spring Bean。 If you don't simply declare a bean for it.如果你不简单地为它声明一个bean。 All it needs is a ListableBeanFactory
.它所需要的只是一个ListableBeanFactory
。
With Spring Data REST in the picture on might get into the need to lookup the repository that's backing a particular path segment of the URI.使用 Spring Data REST 可能需要查找支持 URI 特定路径段的存储库。 That additional knowledge is encoded in RepositoryResourceMappings
which can be used to find out about the domain type that's accessed:这些额外的知识在RepositoryResourceMappings
中编码,可用于查找访问的域类型:
RepositoryResourceMappings mappings = … // get injected
Optional<Class<?>> domainType = mappings.stream()
.filter(metadata -> metadata.getPath().matches(pathSegment))
.findFirst()
.map(ResourceMetadata::getDomainType);
The discovered type can now be used to obtain the repository instance from Repositories
.现在可以使用发现的类型从Repositories
获取存储库实例。 Spring Data REST also provides a preconfigured instance of RepositoryInvokerFactory
that applies potentially registered custom EntityLookup
instances. Spring Data REST 还提供了一个预配置的RepositoryInvokerFactory
实例,用于应用潜在注册的自定义EntityLookup
实例。 Ie using that is preferred to creating an own one like shown above.即使用它是首选创建自己的,如上所示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.