Table of Contents
You can declare Hazelcast beans for Spring context using beans namespace (default spring beans namespace) as well to declare hazelcast maps, queues and others. Hazelcast-Spring integration requires either hazelcast-spring jar or hazelcast-all jar in the classpath.
<bean id="instance" class="com.hazelcast.core.Hazelcast" factory-method="newHazelcastInstance">
<constructor-arg>
<bean class="com.hazelcast.config.Config">
<property name="groupConfig">
<bean class="com.hazelcast.config.GroupConfig">
<property name="name" value="dev"/>
<property name="password" value="pwd"/>
</bean>
</property>
<!-- and so on ... -->
</bean>
</constructor-arg>
</bean>
<bean id="map" factory-bean="instance" factory-method="getMap">
<constructor-arg value="map"/>
</bean>
Hazelcast has Spring integration (requires version 2.5 or greater) since 1.9.1 using hazelcast namespace.
Add namespace xmlns:hz="http://www.hazelcast.com/schema/spring" to beans tag in context file:
<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-2.5.xsd
http://www.hazelcast.com/schema/spring
http://www.hazelcast.com/schema/spring/hazelcast-spring-2.3.xsd">
Use hz namespace shortcuts to declare cluster, its items and so on.
After that you can configure Hazelcast instance (node):
<hz:hazelcast id="instance">
<hz:config>
<hz:group name="dev" password="password"/>
<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"
max-size="0"
eviction-percentage="30"
read-backup-data="true"
cache-value="true"
eviction-policy="NONE"
merge-policy="hz.ADD_NEW_ENTRY"/>
</hz:config>
</hz:hazelcast>
You can easily configure map-store and near-cache too. (For map-store you should set either class-name or implementation attribute.)
<hz:config>
<hz:map name="map1">
<hz:near-cache time-to-live-seconds="0" max-idle-seconds="60"
eviction-policy="LRU" max-size="5000" invalidate-on-change="true"/>
<hz:map-store enabled="true" class-name="com.foo.DummyStore"
write-delay-seconds="0"/>
</hz:map>
<hz:map name="map2">
<hz:map-store enabled="true" implementation="dummyMapStore"
write-delay-seconds="0"/>
</hz:map>
<bean id="dummyMapStore" class="com.foo.DummyStore" />
</hz:config>
It's possible to use placeholders instead of concrete values. For instance, use property file app-default.properties for group configuration:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/app-default.properties</value>
</list>
</property>
</bean>
<hz:hazelcast id="instance">
<hz:config>
<hz:group
name="${cluster.group.name}"
password="${cluster.group.password}"/>
<!-- ... -->
</hz:config>
</hz:hazelcast>
Similar for client
<hz:client id="client"
group-name="${cluster.group.name}" group-password="${cluster.group.password}">
<hz:members>10.10.1.2:5701, 10.10.1.3:5701</hz:members>
</hz:client>
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>
You can declare beans for the following Hazelcast objects:
map
multiMap
queue
topic
set
list
executorService
idGenerator
atomicNumber
semaphore
countDownLatch
lock
Example:
<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: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: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:idGenerator id="idGenerator" instance-ref="instance" name="idGenerator"/> <hz:atomicNumber id="atomicNumber" instance-ref="instance" name="atomicNumber"/> <hz:atomicNumber id="semaphore" instance-ref="client" name="semaphore"/> <hz:atomicNumber id="countDownLatch" instance-ref="instance" name="countDownLatch"/> <hz:atomicNumber id="lock" instance-ref="client" name="lock"/>
Injecting Typed Collections/Maps
Spring tries to create a new Map/Collection instance and fill the new instance
by iterating and converting values of the original Map/Collection
(IMap, IQueue etc.) to required types when generic type parameters
of the original Map/Collection and the target property/attribute do not match.
Since Hazelcast Maps/Collections are designed to hold very large data
which a single machine can not carry, iterating through whole values can cause out of memory errors.
To avoid this issue either target property/attribute can be declared as
un-typed Map/Collection
public class SomeBean {
@Autowired
IMap map; // instead of IMap<K, V> map
@Autowired
IQueue queue; // instead of IQueue<E> queue
...
}
or parameters of injection methods (constructor, setter) can be un-typed.
public class SomeBean {
IMap<K, V> map;
IQueue<E> queue;
public SomeBean(IMap map) { // instead of IMap<K, V> map
this.map = map;
}
...
public void setQueue(IQueue queue) { // instead of IQueue<E> queue
this.queue = queue;
}
...
}
For more info see Spring issue-3407 .