SpringData Gemfire 在开发环境中插入假日期

SpringData Gemfire inserting fake date on Dev env

我正在使用 Gemfire 开发一些应用程序,能够在开发环境中提供一些虚假数据会很棒。

因此,我没有像今天那样在代码中执行此操作,而是考虑使用 spring application-context.xml 在我当前正在处理的区域中预加载一些虚拟数据.类似于 DBUnit 所做的事情,但对于 DEV 而不是 Test 范围。 稍后我可以在 Spring 上切换 envs 并且不会加载该数据。

是否可以使用 SpringData Gemfire 将数据添加到本地数据网格?

谢谢!

Spring Data GemFire 不直接支持将数据加载到 GemFire 集群中。但是,SDG/GemFire 开发人员可以通过多种方式加载数据。

  1. 最常见的方法是定义 GemFire CacheLoader attached to the Region. However, this approach is "lazy" and only loads data from a (potentially) external data source on a cache miss. Of course, you could program the logic in the CacheLoader to "prefetch" a number of entries in a somewhat "predictive" manner based on data access patterns. See GemFire's User Guide 以获得更多详细信息。

不过,我们可以做得更好,因为您更有可能 "preload" 特定数据集用于开发目的。

  1. 另一种更有效的技术是使用在您的 Spring ApplicationContext 中注册的 Spring BeanPostProcessor,post 在之后处理您的 "Region" bean初始化。例如...

其中 RegionPutAllBeanPostProcessor 实现为...

package example;

public class RegionPutAllBeanPostProcessor implements BeanPostProcessor {

  private Map regionData;

  private String targetRegionBeanName;

  protected Map getRegionData() {
    return (regionData != null ? regionData : Collections.emptyMap());
  }

  public void setRegionData(final Map regionData) {
    this.regionData = regionData;
  }

  protected String getTargetRegionBeanName() {
    Assert.state(StringUtils.hasText(targetRegionBeanName), "The target Region bean name was not properly specified!");
    return targetBeanName;
  }

  public void setTargetRegionBeanName(final String targetRegionBeanName) {
    Assert.hasText(targetRegionBeanName, "The target Region bean name must be specified!");
    this.targetRegionBeanName = targetRegionBeanName;
  }

  @Override
  public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
    return bean;
  }

  @Override
  @SuppressWarnings("unchecked")
  public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
    if (beanName.equals(getTargetRegionBeanName()) && bean instanceof Region) {
      ((Region) bean).putAll(getRegionData());
    }

    return bean;
  }
}

不难想象您可以注入某种类型的数据源来预填充区域。 RegionPutAllBeanPostProcessor 旨在接受特定区域(基于区域 bean ID)进行填充。因此,您可以定义多个实例,每个实例采用不同的区域和不同的数据源(可能)来填充所选区域。这个BeanPostProcess只是以一个Map作为数据源,当然,它可以是任何Spring托管bean。

最后,通过利用 Spring bean 配置文件确保 RegionPutAllBeanPostProcessor 的这个或多个实例仅在您的 DEV 环境中使用是一件简单的事情...

<beans>
  ...

  <beans profile="DEV">
    <bean class="example.RegionPutAllBeanPostProcessor">
      ...
    </bean>
    ...
  </beans>
</beans>

通常,就预定义数据的 "source" 而言,加载预定义数据集是非常特定于应用程序的。如我的示例所示,源可以像另一个 Map 一样简单。但是,它将是一个 JDBC 数据源,或者可能是一个属性文件,或者,任何与此相关的东西。这通常取决于开发人员的喜好。

不过,添加到 Spring Data GemFire 中可能有用的一件事是从 GemFire 缓存区域快照加载数据。 IE。可能已从 QA 或 UAT 环境中转储的数据,或者甚至可能出于测试目的从 PROD 中清除的数据。有关详细信息,请参阅 GemFire Snapshot Service

另请参阅 JIRA 票证 (SGF-408) 我刚刚申请添加此支持。

希望这能为您提供足够的信息 and/or 想法,让您开始行动。稍后,我将在 SDG 的 XML 命名空间中添加 first-class 支持,用于预加载数据集。

此致, 约翰