Spring Solr - 将多个客户端用于不同的服务

时间:2017-06-07 22:18:22

标签: spring solr spring-data-solr

我正在使用聚合来自多个来源的数据的应用程序。在这种情况下,我需要使用不相关的数据连接到两个不同的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(),并且尝试使用不同的URL创建新的Context,只需使用首先创建的bean覆盖solrClient和solrTemplate bean。如果每个客户端是唯一定义的Solr客户端,则每个客户端都可以正常工作。

简而言之,我如何创建两个(或更多个)不同的Spring Solr客户端,每个客户端连接到不同的URL?

其他信息是对评论的回复......

我试图简单地使用不同的配置重新创建SolrContext类。考虑以下内容:

@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的solrClient,并且在启动期间创建bean时会覆盖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功能无法定位/识别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(而不仅仅是核心)?

2 个答案:

答案 0 :(得分:5)

由于在同一个Spring上下文中有多个相同类型的bean,因此在使用自动装配时需要消除歧义。以下应该有效:

  

第一个Solr服务器的配置

@Configuration
public class PrimarySolrContext {
  @Bean
  public SolrClient primarySolrClient() {
    return new HttpSolrClient(...);
  }

  @Bean("primary")
  public SolrTemplate solrTemplate() {
    return new SolrTemplate(primarySolrClient());
  }
}
  

第二个Solr服务器的配置

@Configuration
public class SecondarySolrContext {
  @Bean
  public SolrClient secondarySolrClient() {
    return new HttpSolrClient(...);
  }

  @Bean("secondary")
  public SolrTemplate solrTemplate() {
    return new SolrTemplate(secondarySolrClient());
  }
}
  

使用SolrTemplate s

@Service
public class SearchService {
  @Autowired
  @Qualifier("primary")
  private SolrTemplate primarySolrTemplate;

  @Autowired
  @Qualifier("secondary")
  private SolrTemplate secondarySolrTemplate;
}

这是因为:

  1. 第一个SolrTemplate直接通过明确的方法调用(SolrClient)引用其primarySolrClient()
  2. 第二个SolrTemplate直接通过明确的方法调用(SolrClient)引用其secondarySolrClient()
  3. 第一个SolrTemplate被明确命名为(@Bean("primary"))。
  4. 第二个SolrTemplate也明确命名(@Bean("secondary"))。
  5. SolrTemplate通过@Qualifier使用其唯一名称明确注入SolrTemplate
  6. 可以以这种方式初始化和注入更多MessageBox.Show(Environment.CurrentDirectory);

    示例项目on Github可以证明这一点。

答案 1 :(得分:0)

为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);
    }
}