最新バージョンの Elasticsearch を統合する Spring Boot 2.1.X に関連する問題

最新バージョンの Elasticsearch を統合する Spring Boot 2.1.X の問題

Spring boot 2 の新バージョンの spring-boot-starter-data-elasticsearch でサポートされている Elasticsearch のバージョンは 2.X ですが、Elasticsearch は実際にはバージョン 6.5.X まで開発されています。Elasticsearch の新機能をより良く使用するために、 spring-boot-starter-data-elasticsearch の依存関係を非推奨にし、代わりに Spring-data-elasticsearch を直接使用して新しいバージョンのサポートを有効にしました。

ここに画像の説明を挿入

実際には、4.X バージョンはすでに Dev 状態にありますが、安定性を考慮して、十分であるという原則に従って、最新の 3.1.3 リリース バージョンを使用します。

まずgradleに依存関係を追加します

   compile('org.springframework.data:spring-data-elasticsearch:3.1.3.RELEASE')

spring-boot-starter-data-elasticsearch の依存関係を削除する必要があることに注意してください。削除しないと、新しいバージョンが使用されません。

yml に elasticsearch 設定を追加する

elasticsearch:
  cluster-name: wetodo-search
  host: 127.0.0.1
  port: 9300
  pool: 5

構成クラスの書き込み

package com.wetodo.api.config;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;

import java.net.InetAddress;

/**
 * @ClassName ElasticConfig
 * @Description ElasticSearch搜索引擎配置
 * @Author wangd
 * @Create 2018-12-02 23:22
 */

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.wetodo.api.dao")
@Slf4j
public class ElasticConfig {
    /**
     * 主机
     */
    @Value("${elasticsearch.host}")
    private String esHost;

    /**
     * 传输层端口,注意和ES的Restful API默认9200端口有区分
     */
    @Value("${elasticsearch.port}")
    private int esPort;

    /**
     * 集群名称
     */
    @Value("${elasticsearch.clustername}")
    private String esClusterName;

    /**
     * 连接池
     */
    @Value("${elasticsearch.pool}")
    private String poolSize;

    @Bean
    public Client client() {
        log.info("开始初始化Elasticsearch");
        try {
            Settings esSettings = Settings.builder()
                    .put("cluster.name", esClusterName)
                    .put("client.transport.sniff", true)//增加嗅探机制,找到ES集群
                    .put("thread_pool.search.size", Integer.parseInt(poolSize))//增加线程池个数,暂时设为5
                    .build();

            //https://www.elastic.co/guide/en/elasticsearch/guide/current/_transport_client_versus_node_client.html

            return new PreBuiltTransportClient(esSettings)
                    .addTransportAddress(new TransportAddress(InetAddress.getByName(esHost), esPort));
        } catch (Exception e) {
            log.error("初始化Elasticsearch失败!", e);
            return null;
        }
    }


    @Bean
    public ElasticsearchOperations elasticsearchTemplate() {
        Client client = client();
        if (client != null) {
            return new ElasticsearchTemplate(client);
        } else {
            //弹出自定义异常对象
            throw new ApiException("初始化Elasticsearch失败!", 100011);
        }
    }

    //Embedded Elasticsearch Server
    /*@Bean
    public ElasticsearchOperations elasticsearchTemplate() {
        return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
    }*/
}

今起動すると例外が報告されます。この例外には長い間悩まされていました。例外情報は次のとおりです。

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'elasticsearchTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.class]: 
Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; 
factoryBeanName=org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; factoryMethodName=elasticsearchTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchDataAutoConfiguration.class]] for bean 'elasticsearchTemplate': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=elasticConfig; 
 factoryMethodName=elasticsearchTemplate; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/wetodo/api/config/ElasticConfig.class]] bound.

ソース コードを比較すると、上記の問題の根本はカスタム Config クラスに挿入された Bean メソッドであることがわかりました。

@Bean
    public ElasticsearchOperations **elasticsearchTemplate**() {
        Client client = client();
        if (client != null) {
            return new ElasticsearchTemplate(client);
        } else {
            //弹出自定义异常对象
            throw new ApiException("初始化Elasticsearch失败!", 100011);
        }
    }

org.springframework.boot.autoconfigure.ElasticsearchDataAutoConfiguration の関数と同じ名前と異なるパラメーターによって引き起こされる関数オーバーロードの競合

@Bean
	@ConditionalOnMissingBean
	@ConditionalOnBean(Client.class)
	public ElasticsearchTemplate elasticsearchTemplate(Client client,
			ElasticsearchConverter converter) {
		try {
			return new ElasticsearchTemplate(client, converter);
		}
		catch (Exception ex) {
			throw new IllegalStateException(ex);
		}
	}

自動設定読み込みクラスにはコンバータがあります。OK、関数名を次のように修正しました。

@Bean
    public ElasticsearchOperations elasticsearchTemplateCustom() {
        Client client = client();
        if (client != null) {
            log.info("初始化Elasticsearch成功!");
            return new ElasticsearchTemplate(client);
        } else {
            //弹出自定义异常对象
            throw new ApiException("初始化Elasticsearch失败!", 100011);
        }
    }

再起動すると問題は解決しました。

application.yml に表示される Spring 独自の自動構成クラスを無効にすることもできます。

spring
    autoconfigure:
    #禁用Spring boot自身的自动配置类
       exclude: org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration

も解決できます。

おすすめ

転載: blog.csdn.net/blackhost/article/details/84769317