2. Bootstrapping GemFire through the Spring container

One of the first tasks when using GemFire and Spring is to configure the data grid through the IoC container. While this is possible out of the box, the configuration tends to be verbose and only address basic cases. To address this problem, the Spring GemFire project provides several classes that enable the configuration of distributed caches or regions to support a variety of scenarios with minimal effort.

2.1 Using the Spring GemFire Namespace

To simplify configuration, SGF provides a dedicated namespace for most of its components. However, one can opt to configure the beans directly through the usual <bean> definition. For more information about XML Schema-based configuration in Spring, see this appendix in the Spring Framework reference documentation.

To use the SGF namespace, one just needs to import it inside the configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:gfe="http://www.springframework.org/schema/gemfire"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">
	<bean id ... >
	
    <gfe:cache ...>
		
</beans>

1

Spring GemFire namespace prefix. Any name can do but through out the reference documentation, the gfe will be used.

2

The namespace URI.

3

The namespace URI location. Note that even though the location points to an external address (which exists and is valid), Spring will resolve the schema locally as it is included in the Spring GemFire library.

4

Declaration example for the GemFire namespace. Notice the prefix usage.

Once declared, the namespace elements can be declared simply by appending the aforementioned prefix. Note that is possible to change the default namespace, for example from <beans> to <gfe>. This is useful for configuration composed mainly of GemFire components as it avoids declaring the prefix. To achieve this, simply swap the namespace prefix declaration above:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/gemfire"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="
	    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	    http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">
	    
    <beans:bean id ... >
	
    <cache ...>
	
</beans>

1

The default namespace declaration for this XML file points to the Spring GemFire namespace.

2

The beans namespace prefix declaration.

3

Bean declaration using the <beans> namespace. Notice the prefix.

4

Bean declaration using the <gfe> namespace. Notice the lack of prefix (as the default namespace is used).

For the remainder of this doc, to improve readability, the XML examples will simply refer to the <gfe> namespace without the namespace declaration, where possible.

2.2 Configuring the GemFire Cache

In order to use the GemFire Fabric, one needs to either create a new Cache or connect to an existing one. As in the current version of GemFire, there can be only one opened cache per VM (or classloader to be technically correct). In most cases the cache is created once and then all other consumers connect to it.

In its simplest form, a cache can be defined in one line:

<gfe:cache />

The declaration above declares a bean(CacheFactoryBean) for the GemFire Cache, named gemfire-cache. All the other SGF components use this naming convention if no name is specified, allowing for very concise configurations. The definition above will try to connect to an existing cache and, in case one does not exist, create it. Since no additional properties were specified the created cache uses the default cache configuration.Especially in environments with opened caches, this basic configuration can go a long way.

For scenarios where the cache needs to be configured, the user can pass in a reference the GemFire configuration file:

<gfe:cache id="cache-with-xml" cache-xml-location="classpath:cache.xml"/>

In this example, if the cache needs to be created, it will use the file named cache.xml located in the classpath root. Only if the cache is created will the configuration file be used.

[Note]Note

Note that the configuration makes use of Spring's Resource abstraction to locate the file. This allows various search patterns to be used, depending on the running environment or the prefix specified (if any) by the value.

In addition to referencing an external configuration file one can specify GemFire settings directly through Java Properties. This can be quite handy when just a few settings need to be changed.

To setup properties one can either use the properties element inside the util namespace to declare or load properties files (the latter is recommended for externalizing environment specific settings outside the application configuration):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:gfe="http://www.springframework.org/schema/gemfire"
    xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
        
     <gfe:cache id="cache-with-xml" cache-xml-location="classpath:cache.xml" properties-ref="props"/>
	 
     <util:properties id="props" location="classpath:/deployment/env.properties"/>
</beans>

Or can use fallback to a raw <beans> declaration:

<bean id="cache-with-props" class="org.springframework.data.gemfire.CacheFactoryBean">
    <property name="properties">
        <props>
           <prop key="bind-address">127.0.0.1</prop>
        </props>
    </property>
</bean>

In this last example, the SGF classes are declared and configured directly without relying on the namespace. As one can tell, this approach is a generic one, exposing more of the backing infrastructure.

It is worth pointing out again, that the cache settings apply only if the cache needs to be created, there is no opened cache in existence otherwise the existing cache will be used and the configuration will simply be discarded.

2.2.1 Configuring a GemFire CacheServer

In Spring GemFire 1.1 dedicated support for configuring a CacheServer was added through the org.springframework.data.gemfire.server package allowing complete configuration through the Spring container:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:gfe="http://www.springframework.org/schema/gemfire"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

	<gfe:cache />
	
	<!-- Advanced example depicting various cache server configuration options -->
	<gfe:cache-server id="advanced-config" auto-startup="true"
		bind-address="localhost" port="${gfe.port.6}" host-name-for-clients="localhost"
		load-poll-interval="2000" max-connections="22" max-threads="16"
		max-message-count="1000" max-time-between-pings="30000"
		groups="test-server">

		<gfe:subscription-config eviction-type="ENTRY" capacity="1000" disk-store="file://${java.io.tmpdir}"/>
	</gfe:cache-server>

	<context:property-placeholder location="classpath:port.properties" />
</beans>

The configuration above shows the dedicated namespace support (through the cache-server element) and the pleothera of options available. Note that rather then just hard-coding the port, this config uses Spring util namespace to read it from a properties file and then replace it at runtime allowing administrators to change it without having to touch the main application config. Through Spring's property placeholder support, SpEL and the environment abstraction one can externalize environment specific properties from the main code base easing the deployment across multiple machines.

[Note]Note

To avoid initialization problems, the CacheServers started by SGF will start after the container has been fully initialized. This allows potential regions, listener, writers or instantiators defined declaratively to be fully initialized and registered before the server starts accepting connections. Keep this in mind when doing programmatic configuration of the items above as the server might start before your components and thus not be seen by the clients connecting right away.

2.2.2 Configuring a GemFire ClientCache

Another configuration addition in SGF 1.1 is the dedicated support for configuring ClientCache - similar to a cache (in both usage and definition) - through the org.springframework.data.gemfire.client package and in particular ClientCacheFactoryBean.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:gfe="http://www.springframework.org/schema/gemfire"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">
        
    <gfe:client-cache />
     
</beans>

client-cache supports much of the same options as the cache element. However as oppose to a vanilla cache, a client cache connects to a server through a pool (by default a pool is created to connect to a server on localhost and 40404 - the default pool is used by all client cache regions (unless configured to use a different pool)).

Pools can be defined through the pool; in case of client caches and regions pools can be used to customize the connectivity to the server for individual entities or for the entire cache. For example, to custommize the default pool used by client-cache, one needs to define a pool and wire it to cache definition:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:gfe="http://www.springframework.org/schema/gemfire"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd">
        
	<gfe:client-cache id="simple" pool-name="my-pool"/>

	<gfe:pool id="my-pool" subscription-enabled="true">
	    <gfe:locator host="someHost" port="43210"/>
	</gfe:pool>
	 
</beans>

2.3 Configuring a GemFire Region

Once the Cache is configured, one needs to configure one or more Regions to interact with the data fabric. SGF allows various region types to be configured and created directly from Spring or in case they are created directly in GemFire, retrieved as such.

For more information about the various region types and their capabilities as well as configuration options, please refer to the GemFire Developer's Guide and community site.

2.3.1 Using an externaly configured Region

For consuming but not creating Regions (for example in case, the regions are already configured through GemFire native configuration, the cache.xml), one can use the lookup-region element. Simply declare the target region name the name attribute; for example to declare a bean definition, named region-bean for an existing region named orders one can use the following definition:

<gfe:lookup-region id="region-bean" name="orders"/>

If the name is not specified, the bean name will be used automatically. The example above becomes:

<!-- lookup for a region called 'orders' -->
<gfe:lookup-region id="orders"/>
[Note]Note

If the region does not exist, an initialization exception will be thrown. For configuring new GemFire regions proceed to the sections below for replicated, partitioned, client or advanced region configuration.

Note that in the previous examples, since no cache name was defined, the default SGF naming convention (gemfire-cache) was used. If that is not an option, one can point to the cache bean through the cache-ref attribute:

<gfe:cache id="cache"/>
		
<gfe:lookup-region id="region-bean" name="orders" cache-ref="cache"/>

The lookup-region provides a simple way of retrieving existing, pre-configured regions without exposing the region semantics or setup infrastructure.

2.3.2 Replicated Region

One of the common region types supported by GemFire is replicated region or replica. In short:

[Note]What is a replica?
When a region is configured to be a replicated region, every member that hosts that region stores a copy of the contents of the region locally. Any update to a replicated region is distributed to all copies of the region. [...] When a replica is created, it goes through an initialization stage in which it discovers other replicas and automatically copies all the entries. While one replica is initializing you can still continue to use the other replicas.

SGF offers a dedicated element for creating replicas in the form of replicated-region element. A minimal declaration looks as follows (again, the example will not setup the cache wiring, relying on the SGF namespace naming conventions):

<gfe:replicated-region id="simple-replica" />

Here, a replicated region is created (if one doesn't exist already). The name of the region is the same as the bean name (simple-replica) and the bean assumes the existence of a GemFire cache named gemfire-cache.

When setting a region, it's fairly common to associate various CacheLoaders, CacheListeners and CacheWriters with it. These components can be either referrenced or declared inlined by the region declaration.

[Note]Note

Following the GemFire recommandations, the namespace allows for each region created multiple listeners but only one cache writer and cache loader. This restriction can be relaxed, for advanced usages by using the beans declaration (see the next section).

Below is an example, showing both styles:

<gfe:replicated-region id="mixed">
    <gfe:cache-listener>
    	<!-- nested cache listener reference -->
        <ref bean="c-listener"/>
        <!-- nested cache listener declaration -->
        <bean class="some.pkg.SimpleCacheListener"/>
    </gfe:cache-listener>
    <!-- loader reference -->
    <gfe:cache-loader ref="c-loader"/>
    <!-- writer reference -->
    <gfe:cache-writer ref="c-writer"/>
</gfe:replicated-region>
[Warning]Warning

Using ref and a nested declaration on cache-listener, cache-loader or cache-writer is illegal. The two options are mutually exclusive and using them at the same time, on the same element will throw an exception.

replicated-region Options

The following table offers a quick overview of the most important configuration options names, possible values and short descriptions for each of settings supported by the replicated-region element. Please see the storage and eviction section for the relevant configuration.

Table 2.1. replicated-region options

NameValuesDescription
idany valid bean nameThe id of the region bean definition.
nameany valid region nameThe name of the region definition. If no specified, it will have the value of the id attribute (that is, the bean name).
cache-refGemFire cache bean nameThe name of the bean defining the GemFire cache (by default 'gemfire-cache').
cache-listenervalid bean name or definitionThe name or nested bean declaration of a GemFire CacheListener.
cache-loadervalid bean name or definitionThe name or nested bean declaration of a GemFire CacheLoader.
cache-writervalid bean name or definitionThe name or nested bean declaration of a GemFire CacheWriter.

2.3.3 Partition(ed) Region

Another region type supported out of the box by the SGF namespace, is the partitioned region. To quote again the GemFire docs:

[Note]What is a partition?

A partitioned region is a region where data is divided between peer servers hosting the region so that each peer stores a subset of the data. When using a partitioned region, applications are presented with a logical view of the region that looks like a single map containing all of the data in the region. Reads or writes to this map are transparently routed to the peer that hosts the entry that is the target of the operation. [...] GemFire divides the domain of hashcodes into buckets. Each bucket is assigned to a specific peer, but may be relocated at any time to another peer in order to improve the utilization of resources across the cluster.

A partition can be created by SGF through the partitioned-region element. Its configuration options are similar to that of the replicated-region plus the partion specific features such as the number of redundant copies, total maximum memory, number of buckets, partition resolver and so on. Below is a quick example on setting up a partition region with 2 redundant copies:

<!-- bean definition named 'distributed-partition' backed by a region named 'redundant' with 2 copies 
and a nested resolver declaration  -->
<gfe:partitioned-region id="distributed-partition" copies="2" total-buckets="4" name="redundant">
    <gfe:partition-resolver>
        <bean class="some.pkg.SimplePartitionResolver"/>
    </gfe:partition-resolver>
</gfe:partitioned-region>

partitioned-region Options

The following table offers a quick overview of the most important configuration options names, possible values and short descriptions for each of settings supported by the partition element. Please see the storage and eviction section for the relevant configuration.

Table 2.2. partitioned-region options

NameValuesDescription
idany valid bean nameThe id of the region bean definition.
nameany valid region nameThe name of the region definition. If no specified, it will have the value of the id attribute (that is, the bean name).
cache-refGemFire cache bean nameThe name of the bean defining the GemFire cache (by default 'gemfire-cache').
cache-listenervalid bean name or definitionThe name or nested bean declaration of a GemFire CacheListener.
cache-loadervalid bean name or definitionThe name or nested bean declaration of a GemFire CacheLoader.
cache-writervalid bean name or definitionThe name or nested bean declaration of a GemFire CacheWriter.
partition-resolverbean nameThe name of the partitioned resolver used by this region, for custom partitioning.
copies0..4The number of copies for each partition for high-availability. By default, no copies are created meaning there is no redundancy. Each copy provides extra backup at the expense of extra storages.
colocated-withvalid region nameThe name of the partitioned region with which this newly created partitioned region is colocated.
local-max-memorypositive integerThe maximum amount of memory, in megabytes, to be used by the region in this process.
total-max-memoryany integer valueThe maximum amount of memory, in megabytes, to be used by the region in all processes.
recovery-delayany long valueThe delay in milliseconds that existing members will wait before satisfying redundancy after another member crashes. -1 (the default) indicates that redundancy will not be recovered after a failure.
startup-recovery-delayany long valueThe delay in milliseconds that new members will wait before satisfying redundancy. -1 indicates that adding new members will not trigger redundancy recovery. The default is to recover redundancy immediately when a new member is added.

2.3.4 Client Region

GemFire supports various deployment topologies for managing and distributing data. The topic is outside the scope of this documentation however to quickly recap, they can be categoried in short in: peer-to-peer (p2p), client-server (or super-peer cache network) and wide area cache network (or WAN). In the last two scenarios, it is common to declare client regions which connect to a backing cache server (or super peer). SGF offers dedicated support for such configuration through Section 2.2.2, “Configuring a GemFire ClientCache, client-region and pool elements. As the name imply, the former defines a client region while the latter connection pools to be used/shared by the various client regions.

Below is a usual configuration for a client region:

<!-- client region using the default client-cache pool -->
<gfe:client-region id="simple">
    <gfe:cache-listener ref="c-listener"/>
</gfe:client-region>
		
		
<!-- region using its own dedicated pool -->
<gfe:client-region id="complex" pool-name="gemfire-pool">
    <gfe:cache-listener ref="c-listener"/>
</gfe:client-region>
	
<bean id="c-listener" class="some.pkg.SimpleCacheListener"/>

<!-- pool declaration -->	
<gfe:pool id="gemfire-pool" subscription-enabled="true">
    <gfe:locator host="someHost" port="40403"/>
</gfe:pool>

Just as the other region types, client-region allows defining CacheListeners. It also relies on the same naming conventions in case the region name or the cache are not set explicitely. However, it also requires a connection pool to be specified for connecting to the server. Each client can have its own pool or they can share the same one.

For a full list of options to set on the client and especially on the pool, please refer to the SGF schema (Appendix A, Spring GemFire Integration Schema) and the GemFire documentation.

Client Interests

To minimize network traffic, each client can define its own 'interest', pointing out to GemFire, the data it actually needs. In SGF, interests can be defined for each client, both key-based and regular-expression-based types being supported; for example:

<gfe:client-region id="complex" pool-name="gemfire-pool">
    <gfe:key-interest durable="true" result-policy="KEYS">
        <bean id="key" class="java.lang.String">
             <constructor-arg value="someKey" /> 
        </bean>
    </gfe:key-interest>
    <gfe:regex-interest pattern=".*" receive-values="false"/>
</gfe:client-region>

A special key ALL_KEYS means interest is registered for all keys (identical to a regex interest of .*). The receive-values attribute indicates whether or not the values are received for create and update events. If true, values are received; if false, only invalidation events are received - refer to the GemFire documentation for more details.

2.3.5 Configurating Disk Storage

GemFire can use disk as a secondary storage for persisting regions or/and overflow (known as data pagination or eviction to disk). SGF allows such options to be configured directly from Spring through disk-store element available on both replicated-region and partitioned-region as well as client-region. A disk store defines how that particular region can use the disk and how much space it has available. Multiple directories can be defined in a disk store such as in our example below:

<gfe:partitioned-region id="partition-data">
    <gfe:disk-store queue-size="50" auto-compact="true" max-oplog-size="10" synchronous-write="false" time-interval="9999">
        <gfe:disk-dir location="/mainbackup/partition" max-size="999"/>
        <gfe:disk-dir location="/backup2/partition" max-size="999"/>
    </gfe:disk-store> 
</gfe:replicated-region>

In general, for maximum efficiency, it is recommended that each region that accesses the disk uses a disk store configuration.

For the full set of options and their meaning please refer to the Appendix A, Spring GemFire Integration Schema and GemFire documentation.

2.3.6 Data Persistence

Both partitioned and replicated regions can be made persistent. That is:

[Note]What is region persistence?

GemFire ensures that all the data you put into a region that is configured for persistence will be written to disk in a way that it can be recovered the next time you create the region. This allows data to be recovered after a machine or process failure or after an orderly shutdown and restart of GemFire.

With SGF, to enable persistence, simply set to true the persistent attribute on replicated-region, partitioned-region or client-region:

<gfe:partitioned-region id="persitent-partition" persistent="true"/>
[Important]Important

Persistence for partitioned regions is supported from GemFire 6.5 onwards - configuring this option on a previous release will trigger an initialization exception.

When persisting regions, it is recommended to configure the storage through the disk-store element for maximum efficiency.

2.3.7 Data Eviction and Overflowing

Based on various constraints, each region can have an eviction policy in place for evicting data from memory. Currently, in GemFire eviction applies on the least recently used entry (also known as LRU). Evicted entries are either destroyed or paged to disk (also known as overflow).

SGF supports all eviction policies (entry count, memory and heap usage) for both partitioned-region and replicated-region as well as client-region, through the nested eviction element. For example, to configure a partition to overflow to disk if its size is more then 512 MB, one could use the following configuration:

<gfe:partitioned-region id="overflow-partition">
     <gfe:eviction type="MEMORY_SIZE" threshold="512" action="OVERFLOW_TO_DISK"/>
</gfe:partitioned-region>
[Important]Important

Replicas cannot use a local destroy eviction since that would invalidate them. See the GemFire docs for more information.

When configuring regions for oveflow, it is recommended to configure the storage through the disk-store element for maximum efficiency.

For a detailed description of eviction policies, see the GemFire documentation (such as this page).

2.3.8 Advanced Region Configuration

SGF namespaces allow short and easy configuration of the major GemFire regions and associated entities. However, there might be corner cases where the namespaces are not enough, where a certain combination or set of attributes needs to be used. For such situations, using directly the SGF FactoryBeans is a possible alternative as it gives access to the full set of options at the expense of conciseness.

As a warm up, below are some common configurations, declared through raw beans definitions.

A basic configuration looks as follows:

<bean id="basic" class="org.springframework.data.gemfire.RegionFactoryBean">
  <property name="cache">
      <bean class="org.springframework.data.gemfire.CacheFactoryBean"/>
  </property>
  <property name="name" value="basic"/>
</bean>

Notice how the GemFire cache definition has been nested into the declaring region definition. Let's add more regions and make the cache a top level bean.

Since the region bean definition name is usually the same with that of the cache, the name property can be omitted (the bean name will be used automatically). Additionally by using the name the p namespace, the configuration can be simplified even more:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  
    <!-- shared cache across regions -->
    <bean id="cache" class="org.springframework.data.gemfire.CacheFactoryBean"/>

    <!-- region named 'basic' -->
    <bean id="basic" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache"/>

    <!-- region with a name different then the bean definition -->
    <bean id="root-region" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache" p:name="default-region"/>
</beans>

It is worth pointing out, that for the vast majority of cases configuring the cache loader, listener and writer through the Spring container is preferred since the same instances can be reused across multiple regions and additionally, the instances themselves can benefit from the container's rich feature set:

<bean id="cacheLogger" class="org.some.pkg.CacheLogger"/>
<bean id="customized-region" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache">
  <property name="cacheListeners">
    <array>
      <ref name="cacheLogger"/>
    <bean class="org.some.other.pkg.SysoutLogger"/>
    </array>
  </property>
  <property name="cacheLoader"><bean class="org.some.pkg.CacheLoad"/></property>
  <property name="cacheWriter"><bean class="org.some.pkg.CacheWrite"/></property>
</bean>

<bean id="local-region" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache">
  <property name="cacheListeners" ref="cacheLogger"/>	
</bean>

For scenarios where a CacheServer is used and clients need to be configured and the namespace is not an option, SGF offers a dedicated configuration class named: ClientRegionFactoryBean. This allows client interests to be registered in both key and regex form through Interest and RegexInterest classes in the org.springframework.data.gemfire.client package:

<bean id="interested-client" class="org.springframework.data.gemfire.client.ClientRegionFactoryBean" p:cache-ref="cache" p:name="client-region">
  <property name="interests">
    <array>
      <!-- key-based interest -->
      <bean class="org.springframework.data.gemfire.client.Interest" p:key="Vlaicu" p:policy="NONE"/>
      <!-- regex-based interest -->
      <bean class="org.springframework.data.gemfire.client.RegexInterest" p:key=".*" p:policy="KEYS" p:durable="true"/>
    </array>
  </property>
</bean>

Users that need fine control over a region, can configure it in Spring by using the attributes property. To ease declarative configuration in Spring, SGF provides two FactoryBeans for creating RegionAttributes and PartitionAttributes, namely RegionAttributesFactory and PartitionAttributesFactory. See below an example of configuring a partitioned region through Spring XML:

<bean id="partitioned-region" class="org.springframework.data.gemfire.RegionFactoryBean" p:cache-ref="cache">
  <property name="attributes">
    <bean class="org.springframework.data.gemfire.RegionAttributesFactory" p:initial-capacity="1024">
      <property name="partitionAttributes">
        <bean class="org.springframework.data.gemfire.PartitionAttributesFactoryBean" p:redundant-copies="2" p:local-max-memory="512"/>
      </property>
    </bean>
  </property>
</bean>

By using the attribute factories above, one can reduce the size of the cache.xml or even eliminate it all together.

2.4 Advantages of using Spring over GemFire cache.xml

With SGF, GemFire regions, pools and cache can be configured either through Spring or directly inside GemFire, native, cache.xml file. While both are valid approaches, it's worth pointing out that Spring's powerful DI container and AOP functionality makes it very easy to wire GemFire into an application. For example configuring a region cache loader, listener and writer through the Spring container is preferred since the same instances can be reused across multiple regions and additionally are either to configure due to the presence of the DI and eliminates the need of implementing GemFire's Declarable interface (see Section 3.6, “Wiring Declarable components” on chapter on how you can still use them yet benefit from Spring's DI container).

Whatever route one chooses to go, SGF supports both approaches allowing for easy migrate between them without forcing an upfront decision.

2.5 Creating Indecies

GemFire allows creation on indices (or indexes) to improve the performance of (common) queries. SGF allows indecies to be declared through the index element:

<gfe:index id="myIndex" expression="someField" from="/someRegion"/>

Before creating an index, SGF will verify whether one with the same name already exists. If it does, it will compare the properties and if they don't match, will remove the old one to create a new one. If the properties match, SGF will simply return the index (in case it does not exist it will simply create one). To prevent the update of the index, even if the properties do not match, set the property override to false.

Note that index declaration are not bound to a region but rather are top-level elements (just like gfe:cache). This allows one to declare any number of indecies on any region whether they are just created or already exist - an improvement versus the GemFire cache.xml. By default the index relies on the default cache declaration but one can customize it accordingly or use a pool (if need be) - see the namespace schema for the full set of options.