转载自:
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).
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 :
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;
/** * @author onlinetechvision.com
* @since 15 Oct 2011
* @version 1.0.0
*
*/
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;
/** * @author onlinetechvision.com
* @since 15 Oct 2011
* @version 1.0.0
*
*/
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;
/** * @author onlinetechvision.com
* @since 15 Oct 2011
* @version 1.0.0
*
*/
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;
/** * @author onlinetechvision.com
* @since 15 Oct 2011
* @version 1.0.0
*
*/
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;
/** * @author onlinetechvision.com
* @since 15 Oct 2011
* @version 1.0.0
*
*/
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
相关推荐
Ajax in Action helps you implement that thinking--it explains how to distribute the application between the client and the server
Explore the common problems developers face when using Xcode, and find out how to get the most out of your IDE. Dig into Xcode, and you’ll discover it’s richer and more powerful than you might have...
How to distribute your app to beta testers, prepare for the App Store and speed up development time by learning shortcuts and other enhancements to developer tools 仅供学习交流,下载后24小时请删除
Elixir in Action teaches you how to solve practical problems of scalability, concurrency, fault tolerance, and high availability using Elixir. You’ll start with the language, learning basic ...
This one-of-a-kind short ...How to distribute Android TV apps Audience:Developers with some experience with Android development who are interested in building applications for the Android TV platform.
How to distribute your application via the Windows Phone Marketplace Who this book is for Existing .NET and Windows Mobile developers will find this book of great use. Developers moving to Windows ...
Understand how to work with device data using isolated storage, LINQ, and XML serialization How your application can be extended into the cloud using push notifications and web-based services. To ...
In addition to this, the book covers several practical recipes about how to distribute your content with CloudFront, secure your content with IAM, optimize Amazon S3 performance, and notify S3 events...
FireEye Uncovers CVE-2017-8759: Zero-Day Used in the Wild to Distribute FINSPY 火眼公司2017年发布的CVE-2017-8759 0day漏洞在野利用报告
In the concluding chapters, you'll discover how to distribute to the main desktop marketplaces and distribution channels. By the end of this book, you'll be a confident GUI developer who can use the...
Optimize your Amazon S3 bucket by following step-by-step instructions of how to deliver your content with CloudFront, secure the S3 bucket with IAM, and lower costs with object life cycle management ...
Series: Protocollen Voor De...How to distribute Android TV apps Audience:Developers with some experience with Android development who are interested in building applications for the Android TV platform.
Series: Protocollen Voor De...How to distribute Android TV apps Audience:Developers with some experience with Android development who are interested in building applications for the Android TV platform.
Learning TensorFlow: A Guide to Building Deep Learning Systems ...Learn how to scale TensorFlow, and use clusters to distribute model training Deploy TensorFlow in a production setting
How to distribute Android TV apps Audience:Developers with some experience with Android development who are interested in building applications for the Android TV platform. Table of Contents Chapter ...
The book concludes by demonstrating how to package and deploy your finished app on the Google Play store. Table of Contents Chapter 1: Setting up the Development Environment Chapter 2: Building a UI ...
distribute o.7.3版本,自己测试使用,可以使用。欢迎下载
•Learn how to scale TensorFlow, and use clusters to distribute model training •Deploy TensorFlow in a production setting Table of Contents Chapter 1 Introduction Chapter 2 Go with the Flow: Up and...
Learn how to distribute OpenStack services among cluster setup Compare different storage solutions and driver extensions Design different high availability scenarios and how to plan for a no Single ...
You’ll create asynchronous and parallel code, and learn how to distribute the application’s components using Windows Communication Foundation (WCF). You’ll also apply the Model-View-ViewModel ...