Spring Solr - 将多个客户端用于不同的服务
Spring Solr - Using multiple clients to different services
我正在使用一个聚合来自多个来源的数据的应用程序。在这种情况下,我需要使用不相关的数据连接到两个不同的 Solr 服务。为此,我建立了两个不同的数据存储库。我将 bean 定义如下:
@Configuration
@EnableSolrRepositories(basePackages={"foo.utilities.solr.repos.gcr"}, multicoreSupport=true)
public class GcrSolrContext {
@Bean
public SolrClient solrClient() {
return new HttpSolrClient("http://foo:8086/solr/gcr");
}
@Bean
public SolrTemplate solrTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}
我遇到的问题是我不知道如何拥有两个完全独立的 Solr 客户端,每个客户端都指向不同的 url。由于需要 bean solrClient() 和 solrTemplate(),并且尝试创建具有不同 URLs 的新 Context 只会让 solrClient 和 solrTemplate bean 被首先创建的 bean 覆盖。如果每个客户端是唯一定义的 Solr 客户端,它们都可以正常工作。
简而言之,我如何创建两个(或更多)不同的 Spring Solr 客户端,每个都连接到不同的 URLS?
附加信息是对评论的回应...
我试图用以下不同的 configurations.Consider 简单地重新创建 SolrContext class:
@Configuration
@EnableSolrRepositories(basePackages={"foo.utilities.solr.repos.different"}, multicoreSupport=true)
public class DifferentSolrContext {
@Bean
public SolrClient solrClient() {
return new HttpSolrClient("http://SomethingDifferent:8086/solr/something");
}
@Bean
public SolrTemplate solrTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}
这里发生的是在启动期间创建 bean 时 @Bean 的 solrClient 和 solrTemplate 被覆盖。
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'solrClient' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=yyySolrContext; factoryMethodName=solrClient; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.GcrSolrContext] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=xxxSolrContext; factoryMethodName=solrClient; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.XxxSolrContext]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'solrTemplate' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=yyySolrContext; factoryMethodName=solrTemplate; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.GcrSolrContext] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=haystackSolrContext; factoryMethodName=solrTemplate; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.XxxSolrContext]
测试表明 URL 确实只是第一个实例化的 bean。我还尝试将第二个上下文 bean 重命名为其他名称,但是 Solr 功能无法 locate/identify bean。
这是在尝试定义多个 SolrClient 时抛出的错误。
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.apache.solr.client.solrj.SolrClient' available: expected single matching bean but found 2: solrClient2,solrClient
简而言之,对于 Spring Solr 数据库,似乎只有一个 URL 是可能的。 (注意:使用版本 2.1.4)是否有人在 Spring Solr 数据下工作超过一个 URL(不仅仅是核心)?
为 spring 创建另一个 bean 以使用 solr,这既简单又干净:
@Configuration
@EnableSolrRepositories(basePackages={"foo.utilities.solr.repos.xxx"}, multicoreSupport=true)
public class XXXSolrContext {
@Bean
public SolrClient getClient() {
return new HttpSolrClient("http://foo:8086/solr/xxx");
}
@Bean
public SolrTemplate getTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}
由于在同一个 Spring 上下文中有多个相同类型的 bean,因此在使用自动装配时需要消除歧义。以下应该有效:
Configuration for first Solr server
@Configuration
public class PrimarySolrContext {
@Bean
public SolrClient primarySolrClient() {
return new HttpSolrClient(...);
}
@Bean("primary")
public SolrTemplate solrTemplate() {
return new SolrTemplate(primarySolrClient());
}
}
Configuration for second Solr server
@Configuration
public class SecondarySolrContext {
@Bean
public SolrClient secondarySolrClient() {
return new HttpSolrClient(...);
}
@Bean("secondary")
public SolrTemplate solrTemplate() {
return new SolrTemplate(secondarySolrClient());
}
}
Using the SolrTemplate
s
@Service
public class SearchService {
@Autowired
@Qualifier("primary")
private SolrTemplate primarySolrTemplate;
@Autowired
@Qualifier("secondary")
private SolrTemplate secondarySolrTemplate;
}
之所以有效,是因为:
- 第一个
SolrTemplate
通过明确的方法调用(primarySolrClient()
)直接引用它的SolrClient
。
- 第二个
SolrTemplate
通过明确的方法调用(secondarySolrClient()
)直接引用它的SolrClient
。
- 第一个
SolrTemplate
明确命名为 (@Bean("primary")
)。
- 第二个
SolrTemplate
也明确命名为(@Bean("secondary")
)。
SolrTemplate
s 通过 @Qualifier
. 使用其唯一名称明确注入
可以以这种方式初始化和注入更多 SolrTemplate
。
示例项目可用on Github 演示了这一点。
我正在使用一个聚合来自多个来源的数据的应用程序。在这种情况下,我需要使用不相关的数据连接到两个不同的 Solr 服务。为此,我建立了两个不同的数据存储库。我将 bean 定义如下:
@Configuration
@EnableSolrRepositories(basePackages={"foo.utilities.solr.repos.gcr"}, multicoreSupport=true)
public class GcrSolrContext {
@Bean
public SolrClient solrClient() {
return new HttpSolrClient("http://foo:8086/solr/gcr");
}
@Bean
public SolrTemplate solrTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}
我遇到的问题是我不知道如何拥有两个完全独立的 Solr 客户端,每个客户端都指向不同的 url。由于需要 bean solrClient() 和 solrTemplate(),并且尝试创建具有不同 URLs 的新 Context 只会让 solrClient 和 solrTemplate bean 被首先创建的 bean 覆盖。如果每个客户端是唯一定义的 Solr 客户端,它们都可以正常工作。
简而言之,我如何创建两个(或更多)不同的 Spring Solr 客户端,每个都连接到不同的 URLS?
附加信息是对评论的回应...
我试图用以下不同的 configurations.Consider 简单地重新创建 SolrContext class:
@Configuration
@EnableSolrRepositories(basePackages={"foo.utilities.solr.repos.different"}, multicoreSupport=true)
public class DifferentSolrContext {
@Bean
public SolrClient solrClient() {
return new HttpSolrClient("http://SomethingDifferent:8086/solr/something");
}
@Bean
public SolrTemplate solrTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}
这里发生的是在启动期间创建 bean 时 @Bean 的 solrClient 和 solrTemplate 被覆盖。
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'solrClient' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=yyySolrContext; factoryMethodName=solrClient; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.GcrSolrContext] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=xxxSolrContext; factoryMethodName=solrClient; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.XxxSolrContext]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'solrTemplate' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=yyySolrContext; factoryMethodName=solrTemplate; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.GcrSolrContext] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=haystackSolrContext; factoryMethodName=solrTemplate; initMethodName=null; destroyMethodName=(inferred); defined in foo.utilities.solr.XxxSolrContext]
测试表明 URL 确实只是第一个实例化的 bean。我还尝试将第二个上下文 bean 重命名为其他名称,但是 Solr 功能无法 locate/identify bean。
这是在尝试定义多个 SolrClient 时抛出的错误。
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.apache.solr.client.solrj.SolrClient' available: expected single matching bean but found 2: solrClient2,solrClient
简而言之,对于 Spring Solr 数据库,似乎只有一个 URL 是可能的。 (注意:使用版本 2.1.4)是否有人在 Spring Solr 数据下工作超过一个 URL(不仅仅是核心)?
为 spring 创建另一个 bean 以使用 solr,这既简单又干净:
@Configuration
@EnableSolrRepositories(basePackages={"foo.utilities.solr.repos.xxx"}, multicoreSupport=true)
public class XXXSolrContext {
@Bean
public SolrClient getClient() {
return new HttpSolrClient("http://foo:8086/solr/xxx");
}
@Bean
public SolrTemplate getTemplate(SolrClient client) throws Exception {
return new SolrTemplate(client);
}
}
由于在同一个 Spring 上下文中有多个相同类型的 bean,因此在使用自动装配时需要消除歧义。以下应该有效:
Configuration for first Solr server
@Configuration
public class PrimarySolrContext {
@Bean
public SolrClient primarySolrClient() {
return new HttpSolrClient(...);
}
@Bean("primary")
public SolrTemplate solrTemplate() {
return new SolrTemplate(primarySolrClient());
}
}
Configuration for second Solr server
@Configuration
public class SecondarySolrContext {
@Bean
public SolrClient secondarySolrClient() {
return new HttpSolrClient(...);
}
@Bean("secondary")
public SolrTemplate solrTemplate() {
return new SolrTemplate(secondarySolrClient());
}
}
Using the
SolrTemplate
s
@Service
public class SearchService {
@Autowired
@Qualifier("primary")
private SolrTemplate primarySolrTemplate;
@Autowired
@Qualifier("secondary")
private SolrTemplate secondarySolrTemplate;
}
之所以有效,是因为:
- 第一个
SolrTemplate
通过明确的方法调用(primarySolrClient()
)直接引用它的SolrClient
。 - 第二个
SolrTemplate
通过明确的方法调用(secondarySolrClient()
)直接引用它的SolrClient
。 - 第一个
SolrTemplate
明确命名为 (@Bean("primary")
)。 - 第二个
SolrTemplate
也明确命名为(@Bean("secondary")
)。 SolrTemplate
s 通过@Qualifier
. 使用其唯一名称明确注入
可以以这种方式初始化和注入更多 SolrTemplate
。
示例项目可用on Github 演示了这一点。