Spring整合Solr7.1:总是需要开拓的勇气

自我更新,需要对技术的热爱,对极致的追求

一.环境说明

  • Windows 10 ver 1709
  • IDEA 2017.2.6
  • Spring 4.3.12
  • Solr 7.1.0

二.开始吧

最近在做solr的升级工作,从4.10升级到最新的7.1,却发现困难难重重.因为相关可参考的资料太少了,能搜到的基本都是停留在solr4或5之类的,而再往上的却只有寥寥,让我这个菜鸟很是忧伤.没办法,只能一步步查源码,翻官方文档,来研究更新了什么.

三.对比

在4.10.3的时候,配置是这样的,新建个applicationSolr.xml,作为solr的配置文件(个人喜好,也可以不单独出来)

首先一个改变就是,在4.10的时候,要配置的是HttpSolrServer,而在7.1的时候,你需要配置的东西改名成HttpSolrClient了

这是solr4.10.3的HttpSolrServer的构造方法

 public HttpSolrServer(String baseURL) {
        this(baseURL, (HttpClient)null, new BinaryResponseParser());
    }

    public HttpSolrServer(String baseURL, HttpClient client) {
        this(baseURL, client, new BinaryResponseParser());
    }

    public HttpSolrServer(String baseURL, HttpClient client, ResponseParser parser) {
        this.requestWriter = new RequestWriter();
        this.followRedirects = false;
        this.maxRetries = 0;
        this.queryParams = Collections.emptySet();
        this.baseUrl = baseURL;
        if (this.baseUrl.endsWith("/")) {
            this.baseUrl = this.baseUrl.substring(0, this.baseUrl.length() - 1);
        }

        if (this.baseUrl.indexOf(63) >= 0) {
            throw new RuntimeException("Invalid base url for solrj.  The base URL must not contain parameters: " + this.baseUrl);
        } else {
            if (client != null) {
                this.httpClient = client;
                this.internalClient = false;
            } else {
                this.internalClient = true;
                ModifiableSolrParams params = new ModifiableSolrParams();
                params.set("maxConnections", 128);
                params.set("maxConnectionsPerHost", 32);
                params.set("followRedirects", this.followRedirects);
                this.httpClient = HttpClientUtil.createClient(params);
            }

            this.parser = parser;
        }
    }

这是solr4.10.3的applicationContextSolr.xml


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg value="solrCore的远程地址"/>
    bean>

beans>

这里是solr7.1的HttpSolrClient构造方法

**
   * @deprecated use {@link HttpSolrClient#HttpSolrClient(Builder)} instead, as it is a more extension/subclassing-friendly alternative
   */
  @Deprecated
  protected HttpSolrClient(String baseURL, HttpClient client, ResponseParser parser, boolean allowCompression) {
    this(new Builder(baseURL)
        .withHttpClient(client)
        .withResponseParser(parser)
        .allowCompression(allowCompression));
  }

  /**
   * The constructor.
   *
   * @param baseURL The base url to communicate with the Solr server
   * @param client Http client instance to use for communication
   * @param parser Response parser instance to use to decode response from Solr server
   * @param allowCompression Should compression be allowed ?
   * @param invariantParams The parameters which should be included with every request.
   * 
   * @deprecated use {@link HttpSolrClient#HttpSolrClient(Builder)} instead, as it is a more extension/subclassing-friendly alternative
   */
  @Deprecated
  protected HttpSolrClient(String baseURL, HttpClient client, ResponseParser parser, boolean allowCompression,
      ModifiableSolrParams invariantParams) {
    this(new Builder(baseURL)
        .withHttpClient(client)
        .withResponseParser(parser)
        .allowCompression(allowCompression)
        .withInvariantParams(invariantParams));
  }

  protected HttpSolrClient(Builder builder) {
    this.baseUrl = builder.baseSolrUrl;
    if (baseUrl.endsWith("/")) {
      baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
    }
    if (baseUrl.indexOf('?') >= 0) {
      throw new RuntimeException(
          "Invalid base url for solrj.  The base URL must not contain parameters: "
              + baseUrl);
    }

    if (builder.httpClient != null) {
      this.httpClient = builder.httpClient;
      this.internalClient = false;
    } else {
      this.internalClient = true;
      ModifiableSolrParams params = new ModifiableSolrParams();
      params.set(HttpClientUtil.PROP_FOLLOW_REDIRECTS, followRedirects);
      params.set(HttpClientUtil.PROP_ALLOW_COMPRESSION, builder.compression);
      httpClient = HttpClientUtil.createClient(params);
    }

    this.parser = builder.responseParser;
    this.invariantParams = builder.invariantParams;
    this.connectionTimeout = builder.connectionTimeoutMillis;
    this.soTimeout = builder.socketTimeoutMillis;
  }

可以看出,在solr最新版的源码中,已经移除了只有baseUrl的构造方法,但是加入了一个接收一个叫Builder的参数的构造方法,那么,Builder是什么?
ctrl+鼠标左键,看到了下面这段代码:

//无参构造
 public Builder() {
      this.responseParser = new BinaryResponseParser();
    }
  /**
     * Create a Builder object, based on the provided Solr URL.
     * 
     * Two different paths can be specified as a part of this URL:
     * 
     * 1) A path pointing directly at a particular core
     * 
     *   SolrClient client = new HttpSolrClient.Builder("http://my-solr-server:8983/solr/core1").build();
     *   QueryResponse resp = client.query(new SolrQuery("*:*"));
     * 
* Note that when a core is provided in the base URL, queries and other requests can be made without mentioning the * core explicitly. However, the client can only send requests to that core. * * 2) The path of the root Solr path ("/solr") *
     *   SolrClient client = new HttpSolrClient.Builder("http://my-solr-server:8983/solr").build();
     *   QueryResponse resp = client.query("core1", new SolrQuery("*:*"));
     * 
* In this case the client is more flexible and can be used to send requests to any cores. This flexibility though * requires that the core be specified on all requests. * * By default, compression is not enabled on created HttpSolrClient objects. */ public Builder(String baseSolrUrl) { this.baseSolrUrl = baseSolrUrl; this.responseParser = new BinaryResponseParser(); }

哈哈,可以看到,原来你需要用baseUrl先构造出来一个Builder对象,然后再用Builder去构造出我们需要的HttpSolrClient对象.
虽然,源码还没研究明白,但总算是解决了问题.
下面就是我们Spring整合Solr7所需的配置文件了


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


<bean id="httpSolrClient" class="org.apache.solr.client.solrj.impl.HttpSolrClient">
    <constructor-arg name="builder" value="solrCore的远程地址"/>
bean>

beans>

2017/11/17
Lucifer

你可能感兴趣的:(记录)