我正在使用Spring Data REST构建一个应用程序,并使用MappedInterceptor
中的post实现拦截器模式。拦截器按预期工作,它拦截@RestControllers
。
现在,使用preHandle(…)
方法签名中可用的参数(包括:HttpServletRequest request, HttpServletResponse response, Object handler => can be casted to org.springframework.web.method.HandlerMethod
),如何访问正在调用的RestRepository类或存储库方法(来自HandlerMethod类的getMethod()
适用于Concrete类,但它不起作用使用Repository接口,它结束返回一个RestAbstractController类,通过反射调用目标存储库)???
为什么我需要这个?
因为,我正在做一个需要访问Repository接口来查找特定业务注释的交叉逻辑,如果注释存在,则会完成一些逻辑(比如设置MDC
特殊值)...
谢谢...
一般查找和使用Spring Data存储库的最灵活方式是通过Repositories
和RepositoryInvoker
抽象。前者提供有关存储库和存储库本身的元数据的按类型查找功能。后者允许在这些存储库上通用调用CRUD和查询方法。这种额外的抽象是必要的,因为Spring Data存储库不必实现特殊的接口,只要它们公开的方法在语法上等同于Spring Data的CrudRepository
中提供的方法。
如果您知道您尝试访问存储库的实际域类,则可以将Repositories
的实例注入到您的类中。这反过来允许您查找实体和存储库信息以及存储库本身。
由于后者不必强制实施专用接口,Repositories.getRepositoryFor(…)
只返回Optional<Object>
,如果你想在存储库中实际执行操作,这对它们没有太大帮助。 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);
}
}
请注意,如果您使用Spring Data REST,则Repositories
实例可用作Spring Bean。如果你不简单地为它声明一个bean。它所需要的只是一个ListableBeanFactory
。
使用Spring Data REST可能需要查找支持URI的特定路径段的存储库。这些额外的知识在RepositoryResourceMappings
中编码,可用于查找访问的域类型:
RepositoryResourceMappings mappings = … // get injected
Optional<Class<?>> domainType = mappings.stream()
.filter(metadata -> metadata.getPath().matches(pathSegment))
.findFirst()
.map(ResourceMetadata::getDomainType);
现在可以使用发现的类型从Repositories
获取存储库实例。 Spring Data REST还提供了一个预先配置的RepositoryInvokerFactory
实例,它应用了可能已注册的自定义EntityLookup
实例。即使用它比创建一个如上所示的自己更好。