【问题标题】:How to prevent running AfterSaveCallback on save如何防止在保存时运行 AfterSaveCallback
【发布时间】:2021-07-21 04:28:14
【问题描述】:

如何防止在某些条件下运行 AfterSaveCallback (say AfterSaveCallback<Foo>)。我们希望避免触发AfterSaveCallback,即使它存在并已注册。如何做到这一点?

参考https://docs.spring.io/spring-data/elasticsearch/docs/4.0.1.RELEASE/api/index.html?org/springframework/data/elasticsearch/core/event/AfterSaveCallback.html

【问题讨论】:

    标签: spring-boot spring-data-elasticsearch


    【解决方案1】:

    AFAIK,Spring Data 不提供开箱即用的此类功能,但您可以通过自己实现它来实现所需的行为。

    AfterSaveCallback 回调由AbstractElasticsearchTemplate 中定义的方法maybeCallbackAfterSave 调用:

    protected <T> T maybeCallbackAfterSave(T entity, IndexCoordinates index) {
    
      if (entityCallbacks != null) {
        return entityCallbacks.callback(AfterSaveCallback.class, entity, index);
      }
    
      return entity;
    }
    

    我们的想法是通过扩展ElasticsearchRestTemplate 来为此方法提供自定义实现。例如:

    public class CustomElasticsearchRestTemplate extends ElasticsearchRestTemplate {
    
      public CustomElasticsearchRestTemplate(RestHighLevelClient client) {
        super(client);
      }
    
      public CustomElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) {
        super(client, elasticsearchConverter);
      }
    
      @Override
      protected <T> T maybeCallbackAfterSave(T entity, IndexCoordinates index) {
        // compute as necessary
        boolean shouldSkipCallback = ...; 
        // if the conditions are met for the callback not to be applied,
        // just return the entity
        if (shouldSkipCallback) {
          return entity;
        }
      
        // else, proceed with the default implementation
        return super.maybeCallbackAfterSave(entity);
      }
    }
    

    根据用例,覆盖maybeCallbackAfterSave 的匿名类也适用。

    然后,单独使用此自定义ElasticsearchRestTemplate 或以您认为合适的方式将其注册为应用程序默认值,例如,通过扩展AbstractElasticsearchConfiguration - 请参阅this great article - 或直接提供您自己的配置 -见this for an example

    该解决方案有一个缺点,即处理通用的T entity 参数。为此,它可能会有所帮助,我们可以将DefaultEntityCallbacks 中为callback processing 定义的代码作为参考,尤其是以下几行:

    Class<T> entityType = (Class<T>) (entity != null ? ClassUtils.getUserClass(entity.getClass())
                    : callbackDiscoverer.resolveDeclaredEntityType(callbackType).getRawClass());
    

    如您所见,他们使用ClassUtils 中的functionality implemented 来检测实际的类类型。

    也许你可以利用这些知识,做一些类似于以下代码的事情来确定是否应该应用回调:

    // Determine the class using one Spring magic
    Class<T> entityType = (Class<T>) 
    ClassUtils.getUserClass(entity.getClass());
    // Then, compare with the appropriate types that should be excluded
    boolean shouldSkipCallback = entityType.isAssignableFrom(Foo.class);
    

    作为替代方案,您可以向您的AfterSaveCallback&lt;T&gt; 实现提供参数化类型T 的类信息:这将允许您根据onAfterSave 上的具体类确定是否应该应用回调方法调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多