spring-boot 整合elasticsearch 7.x(簡(jiǎn)單入門含gitee源碼)

spring-boot 整合elasticsearch 7.x

elasticsearch 下面簡(jiǎn)稱為 es/ES

技術(shù)版本說明

1. springboot .version - 2.5.3
2. jdk .version - 8
3. lombok.version  - version  - 1.18.10
4. hutool-all.version - 5.6.2
5. spring-boot-starter-data-elasticsearch.version - 延用springboot里的版本(即 2.5.3)
  注意: 雖然延用(繼承)  2.5.3 但是有三個(gè)版本必須移除然后選擇自己es對(duì)應(yīng)的版本!
  如下三個(gè): (使用你自己裝的es的版本,例如我的7.7.0)
    elasticsearch-rest-high-level-client - 7.7.0
    elasticsearch-rest-client - 7.7.0
    elasticsearch - 7.7.0
6. fastjson - version - 1.2.75
7. spring-boot-starter-aop - 延用springboot里的版本(即 2.5.3)

源碼地址

gitee地址: https://gitee.com/zjydzyjs/spring-boot-use-case-collection/tree/master/es

為什么選擇這個(gè)版本的springboot?

首先得理解es 6.x 和 7.x 的不同,導(dǎo)致的springboot版本整合不同!

首先,來先跟我一起打開spring-data/elasticsearch官網(wǎng)

來到 3.1 Version

版本關(guān)系

看到如下圖:
spring-data-elasticsearch對(duì)應(yīng)es版本

因?yàn)槲业?ES 版本為7.7.0晤愧,所以我的springboot 版本需要為 2.4.x以上筷厘。

你也應(yīng)該根據(jù)自己的 ES 版本來選擇對(duì)應(yīng)的springboot 版本,或根據(jù)springboot版本選擇對(duì)應(yīng)的 ES 版本卿泽。

那么新版本有什么不一樣?

原文

圖(原文)

譯文
譯文

我在譯文那里標(biāo)了紅框,官方說:

棄用TransportClient使用

那么這是為什么呢?

為什么棄用 TransportClient

在文檔5.1. Transport Client中找到答案

image

譯文:

TransportClient被棄用Elasticsearch 7的银酬,并會(huì)在Elasticsearch 8被移除(見Elasticsearch文檔)震叮。TransportClient只要在使用的 Elasticsearch版本中可用凌箕,Spring Data Elasticsearch 就會(huì)支持它岁忘,但自 4.0 版以來已棄用使用它的類蠢壹。

那官方都說了是 ES 官方放棄了這個(gè) Transport Client ,那我們?nèi)タ纯础?/p>

image

譯文:

在 7.0.0 中已棄用。

TransportClient是贊成不贊成使用的Java的高級(jí)REST客戶端入宦,將在Elasticsearch 8.0被刪除哺徊。該遷移指南描述了所有需要遷移的步驟。

ok了,那么我們就可以知道了,在Spring Data Elasticsearch中應(yīng)該要使用 Java High Level REST Client乾闰。

棄用TransportClient后應(yīng)該用什客戶端?

然后我們繼續(xù)在Spring Data Elasticsearch文檔中找這個(gè)客戶端,

發(fā)現(xiàn)了文檔中的 5.2. High Level REST Client

剛好與Java High Level REST Client 對(duì)應(yīng)上落追。

yml配置說明

如下圖(yml配置):
yml配置
yml 配置(圖)

備注:  我這里只是簡(jiǎn)單配置,如果需要自定義復(fù)雜配置,請(qǐng)自行配置;

提示: 我這里配置的是 ElasticsearchRestClientProperties

為什么這么配置?

先找到 ES 對(duì)應(yīng)自動(dòng)配置;
image

搜索關(guān)鍵字 elasticsearch 得到下圖結(jié)果:

搜索結(jié)果

我們可以看到紅框內(nèi)容,然后點(diǎn)進(jìn)黃框(ctrl+鼠標(biāo)左擊)

得到以下內(nèi)容:

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({ElasticsearchRestTemplate.class})
@AutoConfigureAfter({ElasticsearchRestClientAutoConfiguration.class, ReactiveElasticsearchRestClientAutoConfiguration.class})
@Import({BaseConfiguration.class, RestClientConfiguration.class, ReactiveRestClientConfiguration.class})
public class ElasticsearchDataAutoConfiguration {
    public ElasticsearchDataAutoConfiguration() {
    }
}

@ConditionalOnClass({ElasticsearchRestTemplate.class})

解析: @ConditionalOnClass在 本文@ConditionalOnXXXX系列常用注解可以看到解釋, 即為: "當(dāng)前classpath下存在指定類,則實(shí)例化當(dāng)前Bean"涯肩。

那么現(xiàn)在的意思就是我們的spring工程中有引入ElasticsearchRestTemplate.class就實(shí)例化 ElasticsearchDataAutoConfiguration.class

@AutoConfigureAfter({ElasticsearchRestClientAutoConfiguration.class, ReactiveElasticsearchRestClientAutoConfiguration.class})

解析: 顧名思義, ElasticsearchDataAutoConfiguration.class 加載會(huì)在 {ElasticsearchRestClientAutoConfiguration.class, ReactiveElasticsearchRestClientAutoConfiguration.class}兩個(gè)類之后轿钠。

@Import({BaseConfiguration.class, RestClientConfiguration.class, ReactiveRestClientConfiguration.class})

解析: @Import可以將類加入 IOC 容器,那么這就意味這交給spring去管理了,

它這里共寫了三個(gè)類,因?yàn)槲覀兪腔趓est的高級(jí)客戶端,所以我們要留意RestClientConfiguration,

其他的配置這里不深入講述,可以參照官方文檔!

OK巢钓,剛剛那些內(nèi)容我都已經(jīng)簡(jiǎn)單的講述了,那么我們現(xiàn)在進(jìn)去研究一下,yml配置 ,我們先進(jìn)入 ElasticsearchRestClientProperties.class,顧名思義,它就是配置類!

ElasticsearchRestClientProperties 查看

@ConfigurationProperties(
    prefix = "spring.elasticsearch.rest"
)
public class ElasticsearchRestClientProperties {
    private List<String> uris = new ArrayList(Collections.singletonList("http://localhost:9200"));
    private String username;
    private String password;
    private Duration connectionTimeout = Duration.ofSeconds(1L);
    private Duration readTimeout = Duration.ofSeconds(30L);
    private final ElasticsearchRestClientProperties.Sniffer sniffer = new ElasticsearchRestClientProperties.Sniffer();

    public ElasticsearchRestClientProperties() {
    }

    public List<String> getUris() {
        return this.uris;
    }

    public void setUris(List<String> uris) {
        this.uris = uris;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Duration getConnectionTimeout() {
        return this.connectionTimeout;
    }

    public void setConnectionTimeout(Duration connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public Duration getReadTimeout() {
        return this.readTimeout;
    }

    public void setReadTimeout(Duration readTimeout) {
        this.readTimeout = readTimeout;
    }

    public ElasticsearchRestClientProperties.Sniffer getSniffer() {
        return this.sniffer;
    }

    public static class Sniffer {
        private Duration interval = Duration.ofMinutes(5L);
        private Duration delayAfterFailure = Duration.ofMinutes(1L);

        public Sniffer() {
        }

        public Duration getInterval() {
            return this.interval;
        }

        public void setInterval(Duration interval) {
            this.interval = interval;
        }

        public Duration getDelayAfterFailure() {
            return this.delayAfterFailure;
        }

        public void setDelayAfterFailure(Duration delayAfterFailure) {
            this.delayAfterFailure = delayAfterFailure;
        }
    }
}

相信大家看到

@ConfigurationProperties(
prefix = "spring.elasticsearch.rest"
)

應(yīng)該知道我的yml為什么那么配置了吧!

那么yml 為什么怎么配置就完結(jié)... 撒花??????

那么它到底用的是不是 java High Level REST Client

接下來回到ElasticsearchRestClientAutoConfiguration再進(jìn)入RestHighLevelClientConfiguration.class

得到如下代碼:

//這一個(gè)內(nèi)部類,省略其他部分
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnMissingBean({RestHighLevelClient.class})
    static class RestHighLevelClientConfiguration {
        RestHighLevelClientConfiguration() {
        }

        @Bean
        RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
            return new RestHighLevelClient(restClientBuilder);
        }
    }

OK了,它其實(shí)就是 new RestHighLevelClient(restClientBuilder) 交給spring去管理疗垛。

所以,沒錯(cuò)的,他就是用的 java High Level REST Client症汹。

怎么去 ES 進(jìn)行操作

1. 繼承 ElasticsearchRepository 接口

說明
使用起來就和jpa差不多
實(shí)現(xiàn)
繼承接口,用例如下:
@Repository
public interface DemoElasticsearchRepository extends ElasticsearchRepository<DemoEsDTO,String> {

    List<DemoEsDTO> getByNumber(Integer number);

    List<DemoEsDTO> getByDes(String des);

    void deleteByDes(String des);

}
具體方法命名空間參考官網(wǎng):
https://docs.spring.io/spring-data/elasticsearch/docs/4.2.4/reference/html/#repositories.namespace-reference 下的
附錄 A:命名空間參考
測(cè)試

在類 {@link com.blacktea.es.EsApplicationDaoTests} 下,有部分例子,可以直接了解一下。

底層
它使用的 ES 客戶端是什么贷腕?

我們先點(diǎn)擊 **ElasticsearchRepository**,再點(diǎn)擊**PagingAndSortingRepository**,

有一個(gè)方法:

Page<T> searchSimilar(T var1, @Nullable String[] var2, Pageable var3);

點(diǎn)擊實(shí)現(xiàn) ->

可以看到
public Page<T> searchSimilar(T entity, @Nullable String[] fields, Pageable pageable) {
        Assert.notNull(entity, "Cannot search similar records for 'null'.");
        Assert.notNull(pageable, "'pageable' cannot be 'null'");
        MoreLikeThisQuery query = new MoreLikeThisQuery();
        query.setId(this.stringIdRepresentation(this.extractIdFromBean(entity)));
        query.setPageable(pageable);
        if (fields != null) {
            query.addFields(fields);
        }

        SearchHits<T> searchHits = (SearchHits)this.execute((operations) -> {
            return operations.search(query, this.entityClass, this.getIndexCoordinates());
        });
        SearchPage<T> searchPage = SearchHitSupport.searchPageFor(searchHits, pageable);
        return (Page)SearchHitSupport.unwrapSearchHits(searchPage);
    }
獲取數(shù)據(jù)的代碼如下:
SearchHits<T> searchHits = (SearchHits)this.execute((operations) -> {
    return operations.search(query, this.entityClass, this.getIndexCoordinates());
});

點(diǎn)擊operations.searc()

進(jìn)入接口 SearchOperations,

再點(diǎn)擊實(shí)現(xiàn)類

得到如圖


image

點(diǎn)擊 ElasticsearchOperations

得到實(shí)現(xiàn)類


image

其實(shí)早在上一步就可以發(fā)現(xiàn)了,當(dāng)前可以用的最終底層實(shí)現(xiàn)就是

ElasticsearchRestTemplate.class

底層實(shí)現(xiàn)圖
image
底層原理解析
public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate {
    private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
    
    // ElasticsearchRestTemplate的底層交互ES的客戶端是 RestHighLevelClient,
    // 說明實(shí)際上我們之前的配置都是對(duì)的!
    // ES 交互的三種方式也是對(duì)的,
    // 1.繼承 ElasticsearchRepository 接口
    // 2.使用 ElasticsearchRestTemplate 類
    // 3.直接使用 RestHighLevelClient 類
    private final RestHighLevelClient client;
    private final ElasticsearchExceptionTranslator exceptionTranslator = new ElasticsearchExceptionTranslator();

    public ElasticsearchRestTemplate(RestHighLevelClient client) {
        Assert.notNull(client, "Client must not be null!");
        this.client = client;
        this.initialize(this.createElasticsearchConverter());
    }

    public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) {
        Assert.notNull(client, "Client must not be null!");
        this.client = client;
        this.initialize(elasticsearchConverter);
    }
}

2. 使用ElasticsearchRestTemplate類

說明
有方法1(繼承 ElasticsearchRepository 接口) 的錨點(diǎn) - **底層原理解析**,可以知道使用該類其實(shí)是對(duì) RestHighLevelClient類執(zhí)行方法的封裝,而繼承接口的方式又是對(duì)該類的封裝,所以你也可以直接使用該類進(jìn)行直接調(diào)用背镇。

3.使用RestHighLevelClient類

說明
既然前面兩種都是基于**RestHighLevelClient**類,進(jìn)行使用的,那么我也可以直接使用該類進(jìn)行調(diào)用,所以我自己寫了個(gè) {@link com.blacktea.es.service.ElasticsearchServiceImpl} 接口服務(wù)(工具類)
測(cè)試
測(cè)試的例子,我大部分都寫在了,{@link com.blacktea.es.EsApplicationTests}
ElasticsearchServiceImpl 說明
該類是我自己在學(xué)習(xí)過程中,參考資料進(jìn)行編寫的,沒有經(jīng)過大數(shù)據(jù)量的測(cè)試,如果需要用于項(xiàng)目中,建議使用方法1(繼承 ElasticsearchRepository 接口)
/**
 * @description: 基于 RestHighLevelClient 封裝的ElasticsearchService
 *
 * @author: black tea
 * @date: 2021/9/6 14:09
 * @version 1.0.0
 */
public interface ElasticsearchService<T> {

    /**
     * 創(chuàng)建文檔,并返回布爾值
     *   當(dāng)索引不存在時(shí),會(huì)自動(dòng)創(chuàng)建
     * @param var2 入?yún)㈩?實(shí)際文檔內(nèi)容)
     * @param index 索引
     * @param id id標(biāo)識(shí)
     * @return true 成功
     * @throws IOException 異常
     */
    boolean createDocument(Object var2, String index, String id) throws IOException;

    /**
     * 創(chuàng)建文檔,并返回創(chuàng)建成功的文檔內(nèi)容
     *   當(dāng)索引不存在時(shí),會(huì)自動(dòng)創(chuàng)建
     * @param var1 返回的對(duì)象類型
     * @param var2 入?yún)㈩?實(shí)際文檔內(nèi)容)
     * @param index 索引
     * @param id id標(biāo)識(shí)
     * @return null 表示失敗
     * @throws IOException 異常
     */
    T createDocument(Class<T> var1,Object var2,String index,String id) throws IOException;

    /**
     * 批量創(chuàng)建文檔
     * @param var 入?yún)ap -> k:id,v:文檔內(nèi)容
     * @param index 索引
     * @return boolean true 成功
     * @throws IOException 異常
     */
    boolean addBatchDocument(Map<String,Object> var,String index) throws IOException;

    /**
     * 通過id標(biāo)識(shí),刪除文檔,并返回布爾值
     *   不會(huì)刪除索引
     * @param index 索引
     * @param id id標(biāo)識(shí)
     * @return true 成功
     * @throws IOException 異常
     */
    boolean deleteDocument(String index, String id) throws IOException;

    /**
     * 根據(jù) ids集合 批量刪除文檔
     * @param index 索引
     * @param ids _id 集合
     * @return boolean
     * @throws IOException 異常
     */
    boolean deleteBatchDocument(String index, List<String> ids) throws IOException;

    /**
     * 按單個(gè)條件(term)刪除文檔,并返回刪除數(shù)量
     *   不會(huì)刪除索引
     * @param index 索引
     * @param key fieldName 字段名稱
     * @param value 字段值
     * @return Long 刪除數(shù)量
     * @throws IOException 異常
     */
    long deleteDocument(String index, String key, Object value) throws IOException;

    /**
     * 根據(jù)多條件進(jìn)行刪除文檔,并返回刪除數(shù)量
     * @param index 索引
     * @param conditionDTOS 自定義條件集合
     * @return Long 刪除數(shù)量
     * @throws IOException 異常
     */
    long deleteDocumentByCondition(String index, List<ESConditionDTO> conditionDTOS) throws IOException;

    /**
     * 根據(jù)id更新文檔,并返回布爾值
     *   當(dāng)索引不存在時(shí),會(huì)自動(dòng)創(chuàng)建
     * @param var2 入?yún)㈩?實(shí)際文檔內(nèi)容)
     * @param index 索引
     * @param id id標(biāo)識(shí)
     * @return true 成功
     * @throws IOException 異常
     */
    boolean updateDocument(Object var2, String index, String id) throws IOException;

    /**
     * 根據(jù)id更新文檔,并返回T
     *
     * @param var1 返回的對(duì)象類型
     * @param var2 修改的內(nèi)容文檔
     * @param index 索引
     * @param id id標(biāo)識(shí)
     * @return T null 表示為修改失敗
     *           失敗原因:
     *              1: 該索引下不存在當(dāng)前id;
     *              2: es修改返回 status = false;
     * @throws IOException
     */
    T updateDocument(Class<T> var1, Object var2, String index, String id) throws IOException;

    /**
     * 根據(jù)多條件進(jìn)行文檔更新,并返回更新數(shù)量
     * @param var2 更新后的文檔內(nèi)容
     * @param index 索引
     * @param conditionDTOS 自定義條件集合
     * @return long 更新數(shù)量
     * @throws IOException 異常
     */
    long updateDocumentByCondition(Object var2, String index, List<ESConditionDTO> conditionDTOS) throws IOException;

    /**
     * 根據(jù) ScriptDto 進(jìn)行文檔更新,并返回更新數(shù)量
     * @param scriptDto {@link ScriptDto} 對(duì)象,包含了需要修改的字段屬性等信息
     * @param index 索引
     * @param conditionDTOS 條件集合(類似于 mysql where 條件)
     * @return long 更新數(shù)量
     * @throws IOException 異常 ESException(自定義)
     */
    long updateDocumentByCondition(ScriptDto scriptDto, String index, List<ESConditionDTO> conditionDTOS) throws IOException;

    /**
     *  根據(jù)Map -> k組成的id進(jìn)行批量更新文檔
     *    Map 的 k 表示更新文檔的 _id,
     *    Map 的 v 表示更新文檔的內(nèi)容 _source
     * @param index 索引
     * @param params 包含id和對(duì)應(yīng)更新文檔內(nèi)容的Map
     * @return boolean
     * @throws IOException 異常
     */
    boolean updateBatchDocument(String index, Map<String,Object> params) throws IOException;

    /**
     * 通過索引下的id獲取該文檔內(nèi)容
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param id id
     * @return T
     * @throws IOException 異常
     */
    T getDocument (Class<T> var1, String index, String id) throws IOException;

    /**
     * 根據(jù) map 條件查詢列表
     *   當(dāng)前查詢操作條件均為 and term
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param map 條件map,當(dāng)前條件操作全部設(shè)置為 term Query
     * @return List<T>
     * @throws IOException 異常
     */
    List<T> getListByAndMap(Class<T> var1, String index, Map<String,Object> map) throws IOException;

    /**
     * 根據(jù) map 條件查詢列表
     *   當(dāng)前查詢操作條件均為 and term
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param map 條件map,當(dāng)前條件操作全部設(shè)置為 term Query
     * @param sortOrderMap 排序Map -> k,v 分別表示排序 字段名稱 和 值({@link org.elasticsearch.search.sort.SortOrder})
     * @return List<T>
     * @throws IOException 異常
     */
    List<T> getListByAndMap(Class<T> var1, String index, Map<String,Object> map ,Map<String, SortOrder> sortOrderMap) throws IOException;

    /**
     * 根據(jù) conditionDos 條件集合 去查詢列表(僅拼接條件)
     *   因?yàn)閑s不支持查詢?nèi)?必須的分頁(yè)查詢,所以查詢所有也是用的分頁(yè)
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param conditionDos 條件集合{@link ESConditionDTO} 根據(jù)該集合對(duì)象進(jìn)行組合
     * @return List<T>
     * @throws IOException 異常 ESException(自定義)
     */
    List<T> getListByCondition(Class<T> var1, String index, List<ESConditionDTO> conditionDos) throws IOException;

    /**
     * 根據(jù) searchDto 條件 去查詢列表(包含拼接條件與排序)
     *   因?yàn)閑s不支持查詢?nèi)?必須的分頁(yè)查詢,所以查詢所有也是用的分頁(yè)
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param searchDto {@link ESSearchDto} 根據(jù)該對(duì)象進(jìn)行組合
     * @return List<T>
     * @throws IOException 異常 ESException(自定義)
     */
    List<T> getListByCondition(Class<T> var1, String index, ESSearchDto searchDto) throws IOException;

    /**
     * 根據(jù)條件進(jìn)行分頁(yè)查詢
     *   {@link PageRequest} 三種分頁(yè)方案, 資料博客: https://blog.csdn.net/pony_maggie/article/details/105478557
     *   1: {@link com.blacktea.es.entites.dto.RequestFromSizePage} from-size -> 占用空間大,可以指定頁(yè)數(shù),但是目前默認(rèn)最大僅支持10000以內(nèi)的分頁(yè)
     *   2: {@link com.blacktea.es.entites.dto.RequestScrollPage} scroll-> 效率高,不可以指定頁(yè)數(shù)且非實(shí)時(shí),但是可以查詢大量數(shù)據(jù),例如 10000以上的list查詢使用!
     *   3: {@link com.blacktea.es.entites.dto.RequestSearchAfterPage} Search_After -> 需要進(jìn)行很深度的分頁(yè),但是可以不指定頁(yè)數(shù)翻頁(yè)泽裳,只要可以實(shí)時(shí)請(qǐng)求下一頁(yè)就行瞒斩。比如一些實(shí)時(shí)滾動(dòng)的場(chǎng)景。
     *
     *  注意: 不建議你去使用除 from-size 外的分頁(yè)方法去實(shí)現(xiàn)指定頁(yè)數(shù)跳轉(zhuǎn)!
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param esSearchDto {@link ESSearchDto} 根據(jù)該對(duì)象進(jìn)行組合
     * @param pageRequest 分頁(yè)對(duì)象,目前共三種 {@link PageRequest} 實(shí)現(xiàn)
     * @return Page<T>
     * @throws IOException 異常 ESException(自定義)
     */
    Page<T> getPageByCondition(Class<T> var1, String index, ESSearchDto esSearchDto, PageRequest pageRequest) throws IOException;

    /**
     * 根據(jù)條件進(jìn)行分頁(yè)查詢
     *   {@link com.blacktea.es.entites.dto.RequestFromSizePage} from-size -> 占用空間大,可以指定頁(yè)數(shù),但是目前默認(rèn)最大僅支持10000以內(nèi)的分頁(yè)
     * @param var1 返回的對(duì)象類型
     * @param index 索引
     * @param esSearchDto {@link ESSearchDto} 根據(jù)該對(duì)象進(jìn)行組合
     * @param requestFromSizePage 分頁(yè)對(duì)象,{@link RequestFromSizePage}
     * @return Page<T>
     * @throws IOException 異常 ESException(自定義)
     */
    Page<T> getPageFromSizeByCondition(Class<T> var1, String index, ESSearchDto esSearchDto, RequestFromSizePage requestFromSizePage) throws IOException;

    /**
     *  獲取指定條件下的數(shù)據(jù)集合數(shù)量(array.size)
     * @param idnex 索引
     * @param query 查詢對(duì)象, 一般為 SearchSourceBuilder.queryBuilder
     * @return long
     * @throws IOException 異常
     */
    Long count(String idnex, QueryBuilder query) throws IOException;
}

@ConditionalOnXXXX系列常用注解

@ConditionalOnBean:當(dāng)給定的在bean存在時(shí),則實(shí)例化當(dāng)前Bean
    
@ConditionalOnMissingBean:當(dāng)給定的在bean不存在時(shí),則實(shí)例化當(dāng)前Bean
    
@ConditionalOnClass:當(dāng)前classpath下存在指定類涮总,則實(shí)例化當(dāng)前Bean
    
@ConditionalOnMissingClass:當(dāng)前classpath下不存在指定類胸囱,則實(shí)例化當(dāng)前Bean
    
@ConditionalOnExpression:依賴于SpEL表達(dá)式值的條件元素的配置注釋,條件為true,則實(shí)例化當(dāng)前bean瀑梗。如:@ConditionalOnExpression("${redis.enabled}==1&&${redis.cluster.enabled:true}&&'${redis.name}'.equals('myredis')")
    
@ConditionalOnWebApplication:當(dāng)Spring為web服務(wù)時(shí)旺矾,才使注解的類生效;通常是配置類夺克;
    
@ConditionalOnProperty:通過@ConditionalOnProperty控制配置類是否生效,可以將配置與代碼進(jìn)行分離,實(shí)現(xiàn)了更好的控制配置箕宙。如:@ConditionalOnProperty(prefix = "filter",name = "loginFilter",havingValue = "true"),配置文件代碼為filter.loginFilter=true铺纽。@ConditionalOnProperty 實(shí)現(xiàn)是通過 havingValue 與配置文件中的值對(duì)比,返回為true則配置類生效,反之失效柬帕。
    
@ConditionalOnResource:僅當(dāng)指定的資源在類路徑上時(shí)才生效。如:@ConditionalOnResource(resources="classpath:jdbc.properties")


感謝

spring-boot 官網(wǎng)

es 官網(wǎng)

https://blog.csdn.net/qq_33375499/article/details/106711248

http://www.reibang.com/p/733e7e1e4de5

b 站 狂神說java

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狡门,一起剝皮案震驚了整個(gè)濱河市陷寝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌其馏,老刑警劉巖凤跑,帶你破解...
    沈念sama閱讀 210,835評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異叛复,居然都是意外死亡仔引,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,900評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門褐奥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咖耘,“玉大人,你說我怎么就攤上這事撬码《梗” “怎么了?”我有些...
    開封第一講書人閱讀 156,481評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵呜笑,是天一觀的道長(zhǎng)夫否。 經(jīng)常有香客問我彻犁,道長(zhǎng),這世上最難降的妖魔是什么凰慈? 我笑而不...
    開封第一講書人閱讀 56,303評(píng)論 1 282
  • 正文 為了忘掉前任汞幢,我火速辦了婚禮,結(jié)果婚禮上溉瓶,老公的妹妹穿的比我還像新娘。我一直安慰自己谤民,他們只是感情好堰酿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,375評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著张足,像睡著了一般触创。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上为牍,一...
    開封第一講書人閱讀 49,729評(píng)論 1 289
  • 那天哼绑,我揣著相機(jī)與錄音,去河邊找鬼碉咆。 笑死抖韩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疫铜。 我是一名探鬼主播茂浮,決...
    沈念sama閱讀 38,877評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼壳咕!你這毒婦竟也來了席揽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,633評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤谓厘,失蹤者是張志新(化名)和其女友劉穎幌羞,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竟稳,經(jīng)...
    沈念sama閱讀 44,088評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡属桦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,443評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了他爸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片地啰。...
    茶點(diǎn)故事閱讀 38,563評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖讲逛,靈堂內(nèi)的尸體忽然破棺而出亏吝,到底是詐尸還是另有隱情,我是刑警寧澤盏混,帶...
    沈念sama閱讀 34,251評(píng)論 4 328
  • 正文 年R本政府宣布蔚鸥,位于F島的核電站惜论,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏止喷。R本人自食惡果不足惜馆类,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,827評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弹谁。 院中可真熱鬧乾巧,春花似錦、人聲如沸预愤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,712評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽植康。三九已至旷太,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間销睁,已是汗流浹背供璧。 一陣腳步聲響...
    開封第一講書人閱讀 31,943評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冻记,地道東北人睡毒。 一個(gè)月前我還...
    沈念sama閱讀 46,240評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冗栗,于是被迫代替她去往敵國(guó)和親吕嘀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,435評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容