天天看點

【轉】How to distribute Spring Beans by using Coherence

轉載自:

         http://www.onlinetechvision.com/?p=425         

          This article shows how to distribute Spring beans by using Coherence. In below sample application, a new cluster named OTV has been created and a spring bean has been distributed by using a cache object named user-map. It has been distributed between two members of the cluster.

Used Technologies :

JDK 1.6.0_21

Spring 3.0.5

Maven 3.0.2

Coherence 3.7.0

SolarisOS 5.10

STEP 1 : CREATE MAVEN PROJECT

A maven project is created as below. (It can be created by using Maven or IDE Plug-in).

【轉】How to distribute Spring Beans by using Coherence

STEP 2 : DOWNLOAD COHERENCE PACKAGE

Coherence package is downloaded via http://www.oracle.com/technetwork/middleware/coherence/downloads/index.html

STEP 3 : LIBRARIES

Firstly, Spring dependencies are added to Maven’ s pom.xml.

?

1 2 3 4 5 6 7 8 9 10 11

<!-- Spring 3 dependencies -->

<

dependency

>

<

groupId

>org.springframework</

groupId

>

<

artifactId

>spring-core</

artifactId

>

<

version

>${spring.version}</

version

>

</

dependency

>

<

dependency

>

<

groupId

>org.springframework</

groupId

>

<

artifactId

>spring-context</

artifactId

>

<

version

>${spring.version}</

version

>

</

dependency

>

Coherence library is installed to Local Maven Repository and its description is added to pom.xml as below. Also if maven is not used, coherence.jar file can be added to classpath.

?

1 2 3 4 5 6

<!-- Coherence library(from local repository) -->

<

dependency

>

<

groupId

>com.tangosol</

groupId

>

<

artifactId

>coherence</

artifactId

>

<

version

>3.7.0</

version

>

</

dependency

>

For creating runnable-jar, below plugin can be used.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

<

plugin

>

<

groupId

>org.apache.maven.plugins</

groupId

>

<

artifactId

>maven-shade-plugin</

artifactId

>

<

version

>1.3.1</

version

>

<

executions

>

<

execution

>

<

phase

>package</

phase

>

<

goals

>

<

goal

>shade</

goal

>

</

goals

>

<

configuration

>

<

transformers

>

<

transformer

implementation

=

"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"

>

<

mainClass

>com.otv.exe.Application</

mainClass

>

</

transformer

>

<

transformer

implementation

=

"org.apache.maven.plugins.shade.resource.AppendingTransformer"

>

<

resource

>META-INF/spring.handlers</

resource

>

</

transformer

>

<

transformer

implementation

=

"org.apache.maven.plugins.shade.resource.AppendingTransformer"

>

<

resource

>META-INF/spring.schemas</

resource

>

</

transformer

>

</

transformers

>

</

configuration

>

</

execution

>

</

executions

>

</

plugin

>

STEP 4 : CREATE otv-coherence-cache-config.xml

otv-coherence-cache-config.xml contains caching-schemes(distributed or replicated) and caching-scheme-mapping configuration. Created cache configuration should be added to coherence-cache-config.xml.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

<?

xml

version

=

"1.0"

?>

<

cache-config

xmlns:xsi

=

"http://www.w3.org/2001/XMLSchema-instance"

xmlns

=

"http://xmlns.oracle.com/coherence/coherence-cache-config"

xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config

coherence-cache-config.xsd">

<

caching-scheme-mapping

>

<

cache-mapping

>

<

cache-name

>user-map</

cache-name

>

<

scheme-name

>MapDistCache</

scheme-name

>

</

cache-mapping

>

</

caching-scheme-mapping

>

<

caching-schemes

>

<

distributed-scheme

>

<

scheme-name

>MapDistCache</

scheme-name

>

<

service-name

>MapDistCache</

service-name

>

<

backing-map-scheme

>

<

local-scheme

>

<

unit-calculator

>BINARY</

unit-calculator

>

</

local-scheme

>

</

backing-map-scheme

>

<

autostart

>true</

autostart

>

</

distributed-scheme

>

</

caching-schemes

>

</

cache-config

>

STEP 5 : CREATE tangosol-coherence-override.xml

tangosol-coherence-override.xml contains cluster, member-identity and configurable-cache-factory configuration. Also below configuration xml file show first member of the cluster.

tangosol-coherence-override.xml for first member of the cluster :

<iframe id="aswift_1" style="margin: 0px; padding: 0px; border-width: 0px; vertical-align: baseline; left: 0px; position: absolute; top: 0px;" name="aswift_1" frame marginwidth="0" marginheight="0" scrolling="no" width="728" height="90"></iframe> ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

<?

xml

version

=

'1.0'

?>

<

coherence

xmlns:xsi

=

"http://www.w3.org/2001/XMLSchema-instance"

xmlns

=

"http://xmlns.oracle.com/coherence/coherence-operational-config"

xsi:schemaLocation

=

"http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd"

>

<

cluster-config

>

<

member-identity

>

<

cluster-name

>OTV</

cluster-name

>

<!-- Name of the first member of the cluster -->

<

role-name

>OTV1</

role-name

>

</

member-identity

>

<

unicast-listener

>

<

well-known-addresses

>

<

socket-address

id

=

"1"

>

<!-- IP Address of the first member of the cluster -->

<

address

>x.x.x.x</

address

>

<

port

>8089</

port

>

</

socket-address

>

<

socket-address

id

=

"2"

>

<!-- IP Address of the second member of the cluster -->

<

address

>y.y.y.y</

address

>

<

port

>8089</

port

>

</

socket-address

>

</

well-known-addresses

>

<!-- Name of the first member of the cluster -->

<

machine-id

>OTV1</

machine-id

>

<!-- IP Address of the first member of the cluster -->

<

address

>x.x.x.x</

address

>

<

port

>8089</

port

>

<

port-auto-adjust

>true</

port-auto-adjust

>

</

unicast-listener

>

</

cluster-config

>

<

configurable-cache-factory-config

>

<

init-params

>

<

init-param

>

<

param-type

>java.lang.String</

param-type

>

<

param-value

system-property

=

"tangosol.coherence.cacheconfig"

>

otv-coherence-cache-config.xml

</

param-value

>

</

init-param

>

</

init-params

>

</

configurable-cache-factory-config

>

</

coherence

>

tangosol-coherence-override.xml for second member of the cluster :

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

<?

xml

version

=

'1.0'

?>

<

coherence

xmlns:xsi

=

"http://www.w3.org/2001/XMLSchema-instance"

xmlns

=

"http://xmlns.oracle.com/coherence/coherence-operational-config"

xsi:schemaLocation

=

"http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd"

>

<

cluster-config

>

<

member-identity

>

<

cluster-name

>OTV</

cluster-name

>

<!-- Name of the second member of the cluster -->

<

role-name

>OTV2</

role-name

>

</

member-identity

>

<

unicast-listener

>     

<

well-known-addresses

>

<

socket-address

id

=

"1"

>

<!-- IP Address of the first member of the cluster -->

<

address

>x.x.x.x</

address

>

<

port

>8089</

port

>

</

socket-address

>

<

socket-address

id

=

"2"

>

<!-- IP Address of the second member of the cluster -->

<

address

>y.y.y.y</

address

>

<

port

>8089</

port

>

</

socket-address

>

</

well-known-addresses

>

<!-- Name of the second member of the cluster -->

<

machine-id

>OTV2</

machine-id

>

<!-- IP Address of the second member of the cluster -->

<

address

>y.y.y.y</

address

>

<

port

>8089</

port

>

<

port-auto-adjust

>true</

port-auto-adjust

>

</

unicast-listener

>

</

cluster-config

>

<

configurable-cache-factory-config

>

<

init-params

>

<

init-param

>

<

param-type

>java.lang.String</

param-type

>

<

param-value

system-property

=

"tangosol.coherence.cacheconfig"

>

otv-coherence-cache-config.xml</

param-value

>

</

init-param

>

</

init-params

>

</

configurable-cache-factory-config

>

</

coherence

>

STEP 6 : CREATE applicationContext.xml

applicationContext.xml is created.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14

<

beans

xmlns

=

"http://www.springframework.org/schema/beans"

xmlns:xsi

=

"http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- Beans Declaration -->

<

bean

id

=

"User"

class

=

"com.otv.user.User"

></

bean

>

<

bean

id

=

"CacheService"

class

=

"com.otv.srv.CacheService"

></

bean

>

<

bean

id

=

"CacheUpdater"

class

=

"com.otv.exe.CacheUpdater"

>

<

property

name

=

"user"

ref

=

"User"

/>

<

property

name

=

"cacheService"

ref

=

"CacheService"

/>

</

bean

>

</

beans

>

STEP 7 : CREATE SPRING BEAN

A new User Spring bean is created. This bean will be distributed between two node in OTV cluster. For serializing,java.io.Serializable interface has been implemented but PortableObject can be implemented for better performance.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

package

com.otv.user;

import

java.io.Serializable;

public

class

User

implements

Serializable {

private

static

final

long

serialVersionUID = 1L;

private

String name;

private

String surname;

public

User(String name, String surname) {

this

.name = name;

this

.surname = surname;

}

public

String getName() {

return

name;

}

public

void

setName(String name) {

this

.name = name;

}

public

String getSurname() {

return

surname;

}

public

void

setSurname(String surname) {

this

.surname = surname;

}

@Override

public

String toString() {

StringBuffer strBuff =

new

StringBuffer();

strBuff.append(

"name : "

).append(name);

strBuff.append(

", surname : "

).append(surname);

return

strBuff.toString();

}

}

STEP 8 : CREATE ICacheService INTERFACE

A new ICacheService Interface is created for service layer.

?

1 2 3 4 5 6 7 8 9 10 11

package

com.otv.srv;

import

com.tangosol.net.NamedCache;

public

interface

ICacheService {

public

NamedCache getCache();

public

void

addToCache(Object key, Object value);

public

void

deleteFromCache(Object key);

}

STEP 9 : CREATE CacheService

CacheService is created for service layer by implementing ICacheService.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

package

com.otv.srv;

import

org.apache.log4j.Logger;

import

com.otv.listener.UserMapListener;

import

com.tangosol.net.CacheFactory;

import

com.tangosol.net.NamedCache;

public

class

CacheService

implements

ICacheService {

private

static

Logger log = Logger.getLogger(CacheService.

class

);

private

NamedCache cache =

null

;

private

static

final

String USER_MAP =

"user-map"

;

private

static

final

long

LOCK_TIMEOUT = -

1

;

public

CacheService() {

cache = CacheFactory.getCache(USER_MAP);

cache.addMapListener(

new

UserMapListener());

}  

public

NamedCache getCache() {

return

cache;

}

public

void

setCache(NamedCache cache) {

this

.cache = cache;

}

public

void

addToCache(Object key, Object value) {

// key is locked

cache.lock(key, LOCK_TIMEOUT);

try

{

// application logic

cache.put(key, value);

}

finally

{

// key is unlocked

cache.unlock(key);

}

}

public

void

deleteFromCache(Object key) {

// key is locked

cache.lock(key, LOCK_TIMEOUT);

try

{

// application logic

cache.remove(key);

}

finally

{

// key is unlocked

cache.unlock(key);

}

}

}

STEP 10 : CREATE USERMAPLISTENER IMPL CLASS

A new UserMapListener class is created. This listener receives distributed user-map events.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

package

com.otv.listener;

import

org.apache.log4j.Logger;

import

com.tangosol.util.MapEvent;

import

com.tangosol.util.MapListener;

public

class

UserMapListener

implements

MapListener {

private

static

Logger logger = Logger.getLogger(UserMapListener.

class

);

public

void

entryDeleted(MapEvent me) {

logger.debug(

"Deleted Key = "

+ me.getKey() +

", Value = "

+ me.getOldValue());

}

public

void

entryInserted(MapEvent me) {

logger.debug(

"Inserted Key = "

+ me.getKey() +

", Value = "

+ me.getNewValue());

}

public

void

entryUpdated(MapEvent me) {

//      logger.debug("Updated Key = " + me.getKey() + ", New_Value = " + me.getNewValue() + ", Old Value = " + me.getOldValue());

}

}

STEP 11 : CREATE CacheUpdater

CacheUpdater Class is created to add new entry to cache and monitor cache content.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

package

com.otv.exe;

import

java.util.Collection;

import

org.apache.log4j.Logger;

import

com.otv.srv.ICacheService;

import

com.otv.user.User;

public

class

CacheUpdater

implements

Runnable {

private

static

Logger log = Logger.getLogger(CacheUpdater.

class

);

ICacheService cacheService;

User user;

public

User getUser() {

return

user;

}

public

void

setUser(User user) {

this

.user = user;

}

public

ICacheService getCacheService() {

return

cacheService;

}

public

void

setCacheService(ICacheService cacheService) {

this

.cacheService = cacheService;

}

public

void

run() {    

//New User are created...

//Entries which will be inserted via first member of the cluster so before the project is built

// in order to deploy first member of the cluster, this code block should be opened...

getUser().setName(

"Bruce"

);

getUser().setSurname(

"Willis"

);

//Entries are added to cache...

getCacheService().addToCache(

"user1"

, getUser());

//      //New User are created...

//      //Entries which will be inserted via second member of the cluster so before the project is built

//      // in order to deploy second member of the cluster, this code block should be opened...

//      getUser().setName("Clint");

//      getUser().setSurname("Eastwood");

//

//      //Entries are added to cache...

//      getCacheService().addToCache("user2", getUser());

//Cache Entries are printed...

printCacheEntries();

}

private

void

printCacheEntries() {

Collection<User> userCollection =

null

;

try

{

while

(

true

) {

userCollection = (Collection<User>)getCacheService().getCache().values();

for

(User user : userCollection) {

log.debug(

"Cache Content : "

+user);

}

Thread.sleep(

10000

);

}

}

catch

(InterruptedException e) {

e.printStackTrace();

}

}

}

STEP 12 : CREATE Application

Application Class is created to run the application.

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

package

com.otv.exe;

import

org.springframework.context.ApplicationContext;

import

org.springframework.context.support.ClassPathXmlApplicationContext;

public

class

Application {

public

static

void

main(String[] args) {

ApplicationContext context =

new

ClassPathXmlApplicationContext(

"applicationContext.xml"

);

CacheUpdater cacheUpdater = (CacheUpdater) context.getBean(

"CacheUpdater"

);

cacheUpdater.run();

}

}

STEP 13 : BUILD PROJECT

After OTV_Spring_Coherence Project is build, OTV_Spring_Coherence-0.0.1-SNAPSHOT.jar will be created.

Important Note : Members of the cluster have got different configurations for Coherence so the project should be built separately for each member.

STEP 14 : RUN PROJECT ON FIRST MEMBER OF THE CLUSTER

After created OTV_Spring_Coherence-0.0.1-SNAPSHOT.jar file is run at the members of the cluster, below output logs will be shown on first member’ s console:

?

1 2 3 4 5 6 7 8 9 10

--A new cluster is created and First Member joins the cluster and adds a new entry to the cache.

15.10.2011 00:52:48 DEBUG (UserMapListener.java:23) - Inserted Key = user1, Value = name : Bruce, surname : Willis

15.10.2011 00:52:48 DEBUG (CacheUpdater.java:51) - Cache Content : name : Bruce, surname : Willis

.......

--Second Member joins the cluster and adds a new entry to the cache.

15.10.2011 00:53:13 DEBUG (UserMapListener.java:23) - Inserted Key = user2, Value = name : Clint, surname : Eastwood

.......

--After second member adds a new entry, cache content is shown as below :

15.10.2011 00:53:19 DEBUG (CacheUpdater.java:51) - Cache Content : name : Clint, surname : Eastwood

15.10.2011 00:53:19 DEBUG (CacheUpdater.java:51) - Cache Content : name : Bruce, surname : Willis

Second member’ s console :

?

1 2 3 4

--After Second Member joins the cluster and adds a new entry to the cache, cache content is shown as below and the members has got same entries :.

15.10.2011 00:53:13 DEBUG (UserMapListener.java:23) - Inserted Key = user2, Value = name : Clint, surname : Eastwood

15.10.2011 00:53:14 DEBUG (CacheUpdater.java:51) - Cache Content : name : Bruce, surname : Willis

15.10.2011 00:53:15 DEBUG (CacheUpdater.java:51) - Cache Content : name : Clint, surname : Eastwood

STEP 15 : DOWNLOAD

OTV_Spring_Coherence

繼續閱讀