通过 Spring Data Gemfire 创建 Gemfire 区域时如何调用 init 方法?

How to invoke init method when Gemfire region gets created via Spring Data Gemfire?

我能够使用如下所示的 Spring Data Gemfire 成功创建 Gemfire 区域 -

<gfe:replicated-region id="myRegion" name="regionName"/>

我现在想在创建数据后立即将其自动加载到我的区域。 所以,我想也许我可以在 区域的 spring 设置。但是它不允许我这样做。

<gfe:replicated-region id="myRegion" name="regionName">
    <gfe:init-method>
        <ref bean="initLoader"/>
    </gfe:init-method>
</gfe:replicated-region>

你能告诉我怎样才能做到这一点吗?谢谢!

是的,SDG core XML namespace (source here) 不允许您这样做。但是,您确实有多种选择。

  1. 首先可以使用GemFire's Snapshot Service, for which Spring Data GemFire provides support.

  2. 其次,您可以创建一个 Spring BeanPostProcessor (relevant docs here) 来在初始化后处理所需的区域以加载一些数据。

我有一个这样的 BeanPostProcessor 的例子 here, configured here, and used in this test class。这是一个非常简单的示例,因为它仅使用另一个 Map 来填充区域(即 RegionTwo),但您可以想象 "regionData" 是您喜欢的任何来源,例如您的 initLoader.

WARNING: You do have to be careful about injecting other beans into a Spring BeanPostProcessors as mentioned in the docs (3rd note down) as you could possibly cause a series of premature bean instantiations that are not subject to the Spring container post processing activities, such as proxying for concerns like Transaction Management. So be careful.

  1. 也可以实现和注册一个SpringApplicationListener in the Spring application context that is autowired with the Region to load, the data source to load the Region with, that then performs the Region data hydrating actions on the ContextRefreshedEvent.

类似...

<bean class="org.example.app.event.MyContextRefreshedEventListener"/>

其中 MyContextRefreshedEventListener 是这样定义的...

package org.example.app.event;

import ...;

class MyContextRefreshedEventListener 
    extends ApplicationListener<ContextRefreshedEvent> {

  @Resource(name = "RegionToLoad")
  Region<?, ?> regionToLoad;

  // Data Source used to hydrate/load the Region on startup
  @Autowired
 DataSource dataSource;

 public void onApplicationEvent(ContextRefreshedEvent event) {
    // load the Region using DataSource
  }
}

当Spring容器启动并刷新时,在所有的bean都被初始化之后,这个ApplicationListener,当在Spring中注册为"bean"时ApplicationContext,将被 Spring 专门针对 ContextRefreshedEvent 触发,然后加载您的区域。

如果您不需要提前加载您的区域,还有其他选项,例如使用 GemFire 的通读、按需缓存区域加载 CacheLoader functionality (docs here)。虽然,正如我提到的,CacheLoader 仅在发生缓存未命中时才会触发,但您仍然可以将 CacheLoader 编码为根据某些启发式方法(应用程序数据访问模式)加载数据块除了返回单个条目未命中。

总之,你会发现真的有很多方法可以做到你所要求的。

如果您对以上信息有更具体的问题,请告诉我。

希望对您有所帮助!

干杯, 约翰