Dependency injection 具有Guice自定义作用域和Jersey的多租户

Dependency injection 具有Guice自定义作用域和Jersey的多租户,dependency-injection,jersey,guice,Dependency Injection,Jersey,Guice,我正在使用Guice for DI开发Jersey的多租户应用程序(我也使用Dropwizard,但我认为这不重要) 困扰我的一件事是,在我的应用程序中到处都是某种租赁id。我的大多数URL如下所示: /:租赁id/一些资源/做一些事情。因此,我的Jersey资源中的方法是使用租户id调用的,并将其交给调用其他服务的服务,依此类推。这些服务针对不同的租户进行了不同的配置 我通过使用@RequestScopedtenacyidrodiver解决了这个问题: 公共类租户IDProvider{ @注入

我正在使用Guice for DI开发Jersey的多租户应用程序(我也使用Dropwizard,但我认为这不重要)

困扰我的一件事是,在我的应用程序中到处都是某种
租赁id
。我的大多数URL如下所示:
/:租赁id/一些资源/做一些事情
。因此,我的Jersey资源中的方法是使用
租户id
调用的,并将其交给调用其他服务的服务,依此类推。这些服务针对不同的租户进行了不同的配置

我通过使用
@RequestScoped
tenacyidrodiver
解决了这个问题:

公共类租户IDProvider{
@注入
公共租户IDProvider(HttpServletRequest请求){
this.request=请求;
}
公共租户ID gettenacyID(){
//从请求中提取租约id
}
}
`

My GuiceModule包含以下方法:

@RequestScoped
公共租户ID getTenancyId(租户ID提供者租户ID工厂){
返回tenancyIdFactory.getTenancyId();
}
public SomeTenancyService getTenancyId(TenancyId TenancyId,配置){
返回新的SomeTenancyService(configuration.getConfiguration(tenancyId));
}
所以现在我不需要担心服务的正确配置。所有这些都由DI容器处理,应用程序与租户无关,不关心租户

我的问题是:
所有这些服务和资源都是在每个请求上创建的,因为它们都具有
@requestscope
依赖关系。这根本不可行。所以我的想法是用guice创建一个自定义范围。因此,每个租户都将获得自己的对象图,并正确配置所有资源和服务(但只配置一次)。我尝试了下面的例子,但我很不确定这是否是可能的Guice的自定义范围。从Jersey的角度来看,我需要在哪里输入自定义范围?
ContainerRequestFilter
是做这件事的正确方法吗?

我终于自己弄明白了。关于Guice的页面是一个很好的起点。不过我需要稍微调整一下

首先,我创建了一个
@tenacyscoped
注释:

@Target({ElementType.TYPE,ElementType.METHOD})
@保留(RetentionPolicy.RUNTIME)
@范围注释
public@interface TenancyScoped{}
然后我使用了一个请求过滤器:

@预匹配
公共类TenancyScopeRequestFilter实现ContainerRequestFilter{
私人最终租赁范围;
@注入
公共租户范围请求筛选器(租户范围){
this.scope=范围;
}
@凌驾
公共无效筛选器(ContainerRequestContext requestContext)引发IOException{
可选tenancyId=getTenancyId(requestContext);
如果(!tenacyId.isPresent()){
scope.exit();
返回;
}
输入(tenacyId.get());
}
私有可选getTenancyId(ContainerRequestContext requestContext){
}
}
请注意
@PreMatching
注释。每个请求都要经过筛选,这一点很重要,否则您的代码可能会表现得异常(范围可能设置不正确)

下面是
tenacyscope
实现:

公共类TenancyScope实现作用域、提供程序{
私有最终记录器Logger=LoggerFactory.getLogger(tenacyscope.class);
private final ThreadLocal,Object>values=new HashMap();
value.put(Key.get(tenacyId.class)、tenacyId);
this.tenacyIDscopedValues.get().putIfAbsent(tenacyID,值);
}
公共无效出口(){
debug(“租约id为{}的退出作用域”,tenacyID.get());
this.tenacyId.set(null);
}
公共提供程序作用域(最终密钥,最终提供程序未作用域){
返回新的提供程序(){
公共部门得不到{
debug(“使用{}键解析对象”,key);

MapHey我在过滤器、注释、GUI等方面面临着许多问题。您能否更完整地发布您的代码,或者提供一些相同的链接?请您提供一些关于“TenancyId”的代码,请提供完整的代码。根据您的使用情况,
TenancyId
只是一个简单的包装字符串或int。没什么特别的,但如果是自定义类型,将所有内容连接在一起会更容易。