Configuring Hazelcast in Spring

Code Sample: See our sample application for Spring Configuration.

Enabling Spring Integration

Classpath Configuration:

To enable Spring integration, hazelcast-spring-5.2.1.jar must be on the classpath.

If you use Maven, add the following lines to your pom.xml:

<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-spring</artifactId>
    <version>5.2.1</version>
</dependency>

If you want to use hazelcast-spring with hazelcast-enterprise, you need to exclude the transitive hazelcast dependency:

<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-enterprise</artifactId>
    <version>5.2.1</version>
</dependency>
<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-spring</artifactId>
    <version>5.2.1</version>
    <exclusions>
        <exclusion>
          <groupId>com.hazelcast</groupId>
          <artifactId>hazelcast</artifactId>
        </exclusion>
    </exclusions>
</dependency>

If you use other build systems, you have to adjust the definition of dependencies to your needs.

Troubleshooting

When the Spring Integration JARs are not correctly installed in the Java classpath, you may see one of the following exceptions:

org.xml.sax.SAXParseException; systemId: http://hazelcast.com/schema/spring/hazelcast-spring.xsd; lineNumber: 2; columnNumber: 35; s4s-elt-character: Non-whitespace characters are not allowed in schema elements other than 'xs:appinfo' and 'xs:documentation'. Saw '301 Moved Permanently'.
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.hazelcast.com/schema/spring]
org.xml.sax.SAXParseException; lineNumber: 25; columnNumber: 33; schema_reference.4: Failed to read schema document 'http://www.hazelcast.com/schema/spring/hazelcast-spring.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>.

In this case, ensure that the required classes are in the classpath as explained in Enabling Spring Integration.

Declaring Beans by Spring beans Namespace

Bean Declaration:

You can declare Hazelcast Objects using the default Spring beans namespace. Example code for a Hazelcast Instance declaration is listed below.

<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
    <constructor-arg>
        <bean class="com.hazelcast.config.Config">
            <property name="clusterName" value="dev"/>
            <!-- and so on ... -->
        </bean>
    </constructor-arg>
</bean>

<bean id="map" factory-bean="instance" factory-method="getMap">
    <constructor-arg value="map"/>
</bean>

Declaring Beans by hazelcast Namespace

Hazelcast has its own namespace hazelcast for bean definitions. You can easily add the namespace declaration xmlns:hz="http://www.hazelcast.com/schema/spring" to the beans element in the context file so that hz namespace shortcut can be used as a bean declaration.

Here is an example schema definition:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:hz="http://www.hazelcast.com/schema/spring"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                http://www.hazelcast.com/schema/spring
                http://www.hazelcast.com/schema/spring/hazelcast-spring.xsd">

Example Configuration

Following is an example Hazelcast configuration when integrated with Spring.

<hz:hazelcast id="instance">
    <hz:config>
        <hz:cluster-name name="dev"/>
        <hz:network port="5701" port-auto-increment="false">
            <hz:join>
                <hz:multicast enabled="false"/>
                <hz:tcp-ip enabled="true">
                    <hz:members>10.10.1.2, 10.10.1.3</hz:members>
                </hz:tcp-ip>
            </hz:join>
        </hz:network>
    </hz:config>
</hz:hazelcast>

Spring Property Placeholders

While configuring Hazelcast within the Spring context, you can also pass values through the Spring property placeholders, as shown below.

<hz:hazelcast id="instance">
    <hz:config>
        <hz:cluster-name>${my.cluster.name}</hz:cluster-name>
        ...
        <hz:network>
            <hz:join>
                <hz:kubernetes service-name="${my.kubernetes.service.name}" />
            </hz:join>
        </hz:network>
    </hz:config>
</hz:hazelcast>

Supported Configurations with hazelcast Namespace

  • Configuring Hazelcast Instance

    <hz:hazelcast id="instance">
        <hz:config>
            <hz:cluster-name name="dev"/>
            <hz:network port="5701" port-auto-increment="false">
                <hz:join>
                    <hz:multicast enabled="false"
                        multicast-group="224.2.2.3"
                        multicast-port="54327"/>
                    <hz:tcp-ip enabled="true">
                        <hz:members>10.10.1.2, 10.10.1.3</hz:members>
                    </hz:tcp-ip>
                </hz:join>
            </hz:network>
            <hz:map name="map"
                backup-count="2"
                read-backup-data="true"
                merge-policy="com.hazelcast.spi.merge.PassThroughMergePolicy">
                <hz:eviction eviction-policy="NONE" size="0"/>
            </hz:map>
        </hz:config>
    </hz:hazelcast>
  • Configuring Hazelcast Client

    <hz:client id="client">
        <hz:cluster-name name="${cluster.name}"/>
        <hz:network connection-timeout="1000"
                    redo-operation="true"
                    smart-routing="true">
            <hz:member>10.10.1.2:5701</hz:member>
            <hz:member>10.10.1.3:5701</hz:member>
        </hz:network>
    </hz:client>
  • Hazelcast Supported Type Configurations and Examples

    • map

    • multiMap

    • replicatedmap

    • queue

    • topic

    • reliableTopic

    • set

    • list

    • executorService

    • durableExecutorService

    • scheduledExecutorService

    • ringbuffer

    • cardinalityEstimator

    • idGenerator

    • flakeIdGenerator

    • atomicLong

    • atomicReference

    • semaphore

    • countDownLatch

    • lock

    • externalDataStore

      <hz:map id="map" instance-ref="client" name="map" lazy-init="true" />
      <hz:multiMap id="multiMap" instance-ref="instance" name="multiMap"
          lazy-init="false" />
      <hz:replicatedMap id="replicatedmap" instance-ref="instance"
          name="replicatedmap" lazy-init="false" />
      <hz:queue id="queue" instance-ref="client" name="queue"
          lazy-init="true" depends-on="instance"/>
      <hz:topic id="topic" instance-ref="instance" name="topic"
          depends-on="instance, client"/>
      <hz:reliableTopic id="reliableTopic" instance-ref="instance" name="reliableTopic"/>
      <hz:set id="set" instance-ref="instance" name="set" />
      <hz:list id="list" instance-ref="instance" name="list"/>
      <hz:executorService id="executorService" instance-ref="client"
          name="executorService"/>
      <hz:durableExecutorService id="durableExec" instance-ref="instance" name="durableExec"/>
      <hz:scheduledExecutorService id="scheduledExec" instance-ref="instance" name="scheduledExec"/>
      <hz:ringbuffer id="ringbuffer" instance-ref="instance" name="ringbuffer"/>
      <hz:cardinalityEstimator id="cardinalityEstimator" instance-ref="instance" name="cardinalityEstimator"/>
      <hz:idGenerator id="idGenerator" instance-ref="instance"
          name="idGenerator"/>
      <hz:flakeIdGenerator id="flakeIdGenerator" instance-ref="instance"
          name="flakeIdGenerator"/>
      <hz:atomicLong id="atomicLong" instance-ref="instance" name="atomicLong"/>
      <hz:atomicReference id="atomicReference" instance-ref="instance"
          name="atomicReference"/>
      <hz:semaphore id="semaphore" instance-ref="instance" name="semaphore"/>
      <hz:countDownLatch id="countDownLatch" instance-ref="instance"
          name="countDownLatch"/>
      <hz:lock id="lock" instance-ref="instance" name="lock"/>
      <hz:external-data-store name="externalStore">
          <hz:class-name>com.hazelcast.datastore.JdbcDataStoreFactory</hz:class-name>
          <hz:properties>
              <hz:property name="jdbcUrl">jdbc:mysql://dummy:3306</hz:property>
          </hz:properties>
      </hz:external-data-store>
  • Supported Spring Bean Attributes

    Hazelcast also supports lazy-init, scope and depends-on bean attributes.

    <hz:hazelcast id="instance" lazy-init="true" scope="singleton">
        ...
    </hz:hazelcast>
    <hz:client id="client" scope="prototype" depends-on="instance">
        ...
    </hz:client>
  • Configuring MapStore and NearCache

    For map-store, you should set either the class-name or the implementation attribute.

    <hz:config id="config">
        <hz:map name="map1">
            <hz:map-store enabled="true" class-name="com.foo.DummyStore"
                write-delay-seconds="0" />
    
            <hz:near-cache time-to-live-seconds="0"
                max-idle-seconds="60" invalidate-on-change="true" >
                <hz:eviction eviction-policy="LRU" size="5000"/>
            </hz:near-cache>
        </hz:map>
    
        <hz:map name="map2">
            <hz:map-store enabled="true" implementation="dummyMapStore"
                write-delay-seconds="0" />
        </hz:map>
    </hz:config>
    
    <bean id="dummyMapStore" class="com.foo.DummyStore" />