Spring Boot 2.1.X整合最新版本Elasticsearch的相关问题

Spring boot 2.1.X整合Elasticsearch最新版的一处问题

新版本的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);
		}
	}

自动配置加载类里,多了个converter。。。。。。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

也可以解决。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值