在Oracle Coherence中分發Spring Bean

本文展示了如何通過使用Oracle Coherence中的EntryProcessor可移植對象格式(POF)功能來分發Spring Bean。

Coherence通過EntryProcessor API支持無鎖編程模型。 此功能通過減少網絡訪問并在條目上執行隱式的低級鎖定來提高系統性能。 此隱式低級鎖定功能與ConcurrentMap API提供的顯式lock(key)不同。

顯式鎖定,Transaction Framework API和Coherence資源適配器是其他作為入口處理器的Coherence事務選項。 有關Coherence交易選項的詳細信息,請參閱參考部分。 另外,對于Coherence顯式鎖定實現,可以建議使用Oracle Coherence文章中的分布式數據管理

可移植對象格式(POF)是獨立于平臺的序列化格式。 它允許將等效的Java,.NET和C ++對象編碼為相同的字節序列。 建議使用POF來提高系統性能,因為POF的序列化和反序列化性能要優于Standart Java序列化(根據Coherence參考文檔,在具有String,long和3個整數的簡單測試類中,(反序列化)為7比Standart Java序列化快十倍)。

Coherence提供了多種緩存類型,例如分布式(或分區),復制,樂觀,近,本地和遠程緩存。 分布式緩存定義為在任意數量的群集節點之間分布(或分區)的數據的集合,這樣,群集中的一個節點就對緩存中的每個數據負責,并且責任是分布式的(或,負載均衡)。 請注意,本文中使用了分布式緩存類型。 由于其他緩存類型不在本文范圍之內,請查看“參考”部分或“ Coherence參考”文檔。 它們的配置與分布式緩存配置非常相似。

如何通過使用覆蓋顯式鎖定的 Coherence文章分發Spring Bean 建議將Java Standart序列化比較兩個不同的實現( EntryProcessor –便攜式對象格式(POF)顯式鎖定– Java Standart序列化 )。

在本文中,創建了一個名為OTV的新集群,并通過使用一個名為user-cache的緩存對象分發了一個spring bean。 它已分布在集群的兩個成員之間。

讓我們看一下實現AbsctractProcessor的實現, 實現為集群中JVM之間的Spring Bean分配實現EntryProcessor接口PortableObject接口

二手技術:

JDK 1.6.0_31
春天3.1.1
連貫性3.7.0 SolarisOS 5.10 Maven的3.0.2

步驟1:建立已完成的專案

創建一個Maven項目,如下所示。 (可以使用Maven或IDE插件來創建它)。

第2步:相干套餐

通過Coherence軟件包下載Coherence

步驟3:圖書館

首先,將Spring依賴項添加到Maven的pom.xml中。 請注意,Coherence庫已安裝到Local Maven Repository,并且其描述如下添加到pom.xml中。 另外,如果未使用Maven,則可以將coherence.jar文件添加到classpath。

<properties><spring.version>3.1.1.RELEASE</spring.version></properties><dependencies><!-- 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(from local repository) --><dependency><groupId>com.tangosol</groupId><artifactId>coherence</artifactId><version>3.7.0</version></dependency><!-- Log4j library --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency></dependencies>

以下maven插件可用于創建runnable-jar。

<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><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.otv.exe.Application</mainClass></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.handlers</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.schemas</resource></transformer></transformers></configuration></execution></executions></plugin>

步驟4:建立otv-pof-config.xml
otv-pof-config.xml涵蓋了使用可移植對象格式(POF)功能進行序列化的類。 在這個例子中; User,UpdateUserProcessorDeleteUserProcessor類實現com.tangosol.io.pof.PortableObject接口。

-Dtangosol.pof.config參數可用于在啟動腳本中定義otv-pof-config.xml路徑。

<?xml version="1.0"?>
<!DOCTYPE pof-config SYSTEM "pof-config.dtd">
<pof-config><user-type-list><!-- coherence POF user types --><include>coherence-pof-config.xml</include><!-- The definition of classes which use Portable Object Format --><user-type><type-id>1001</type-id><class-name>com.otv.user.User</class-name></user-type><user-type><type-id>1002</type-id><class-name>com.otv.user.processor.UpdateUserProcessor</class-name></user-type><user-type><type-id>1003</type-id><class-name>com.otv.user.processor.DeleteUserProcessor</class-name></user-type></user-type-list><allow-interfaces>true</allow-interfaces><allow-subclasses>true</allow-subclasses>
</pof-config>

步驟5:創建otv-coherence-cache-config.xml

otv-coherence-cache-config.xml包含(分布式或復制的)緩存方案和緩存方案映射配置。 創建的緩存配置應添加到coherence-cache-config.xml中

<?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-configcoherence-cache-config.xsd"><caching-scheme-mapping><cache-mapping><cache-name>user-cache</cache-name><scheme-name>UserDistributedCacheWithPof</scheme-name></cache-mapping></caching-scheme-mapping><caching-schemes><distributed-scheme><scheme-name>UserDistributedCacheWithPof</scheme-name><service-name>UserDistributedCacheWithPof</service-name><serializer><instance><class-name>com.tangosol.io.pof.SafeConfigurablePofContext</class-name><init-params><init-param><param-type>String</param-type><param-value><!-- pof-config.xml path should be set-->otv-pof-config.xml</param-value></init-param></init-params></instance></serializer><backing-map-scheme><local-scheme /></backing-map-scheme><autostart>true</autostart></distributed-scheme></caching-schemes></cache-config>

步驟6:創建tangosol-coherence-override.xml

tangosol-coherence-override.xml涵蓋了集群,成員身份和可配置的緩存工廠配置。 另外,以下配置xml文件顯示了群集的第一個成員。 -Dtangosol.coherence.override參數可用于在啟動腳本中定義tangosol-coherence-override.xml路徑。

集群的第一個成員的tangosol-coherence-override.xml:

<?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"><!-- coherence-cache-config.xml path should be set-->otv-coherence-cache-config.xml</param-value></init-param></init-params></configurable-cache-factory-config></coherence>

集群的第二個成員的tangosol-coherence-override.xml:

<?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"><!-- coherence-cache-config.xml path should be set-->otv-coherence-cache-config.xml</param-value></init-param></init-params></configurable-cache-factory-config></coherence>

步驟7:創建applicationContext.xml

applicationContext.xml已創建。

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- Beans Declaration --><bean id="User" class="com.otv.user.User" scope="prototype" /><bean id="UserCacheService" class="com.otv.user.cache.srv.UserCacheService" /><bean id="CacheUpdaterTask" class="com.otv.cache.updater.task.CacheUpdaterTask"><property name="userCacheService" ref="UserCacheService" /></bean>
</beans>

步驟8:建立SystemConstants類別

SystemConstants類已創建。 此類涵蓋所有系統常數。

package com.otv.common;/*** System Constants** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class SystemConstants {public static final String APPLICATION_CONTEXT_FILE_NAME = "applicationContext.xml";//Named Cache Definition...public static final String USER_CACHE = "user-cache";//Bean Names...public static final String BEAN_NAME_CACHE_UPDATER_TASK = "CacheUpdaterTask";public static final String BEAN_NAME_USER = "User";}

步驟9:創建用戶豆

創建了一個新的User Spring bean。 該bean將分布在OTV集群中的兩個節點之間。 可以實現PortableObject進行序列化。 PortableObject Interface有兩個未實現的方法,如readExternalwriteExternal 。 必須定義僅序列化的屬性。 在此示例中,所有屬性(用戶的id,名稱和姓氏)都已序列化。

package com.otv.user;import java.io.IOException;import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;/*** User Bean** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class User implements PortableObject {private String id;private String name;private String surname;/*** Gets User Id** @return String id*/public String getId() {return id;}/*** Sets User Id** @param String id*/public void setId(String id) {this.id = id;}/*** Gets User Name** @return String name*/public String getName() {return name;}/*** Sets User Name** @param String name*/public void setName(String name) {this.name = name;}/*** Gets User Surname** @return String surname*/public String getSurname() {return surname;}/*** Sets User Surname** @param String surname*/public void setSurname(String surname) {this.surname = surname;}@Overridepublic String toString() {StringBuilder strBuilder = new StringBuilder();strBuilder.append("Id : ").append(id);strBuilder.append(", Name : ").append(name);strBuilder.append(", Surname : ").append(surname);return strBuilder.toString();}/*** Restore the contents of a user type instance by reading its state* using the specified PofReader object.** @param PofReader in*/public void readExternal(PofReader in) throws IOException {this.id = in.readString(0);this.name = in.readString(1);this.surname = in.readString(2);}/*** Save the contents of a POF user type instance by writing its state* using the specified PofWriter object.** @param PofWriter out*/public void writeExternal(PofWriter out) throws IOException {out.writeString(0, id);out.writeString(1, name);out.writeString(2, surname);}
}

步驟10:建立IUserCacheService接口

創建了一個新的IUserCacheService接口以執行緩存操作。

package com.otv.user.cache.srv;import com.otv.user.User;
import com.otv.user.processor.DeleteUserProcessor;
import com.otv.user.processor.UpdateUserProcessor;
import com.tangosol.net.NamedCache;/*** User Cache Service Interface** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public interface IUserCacheService {/*** Gets Distributed User Cache** @return NamedCache User Cache*/NamedCache getUserCache();/*** Adds user to cache** @param User user*/void addUser(User user);/*** Updates user on the cache** @param String userId* @param UpdateUserProcessor processor**/void updateUser(String userId, UpdateUserProcessor processor);/*** Deletes user from the cache** @param String userId* @param DeleteUserProcessor processor**/void deleteUser(String userId, DeleteUserProcessor processor);}

步驟11:創建UserCacheService類

通過實現IUserCacheService接口創建UserCacheService類。

package com.otv.user.cache.srv;import com.otv.cache.listener.UserMapListener;
import com.otv.common.SystemConstants;
import com.otv.user.User;
import com.otv.user.processor.DeleteUserProcessor;
import com.otv.user.processor.UpdateUserProcessor;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;/*** User Cache Service** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class UserCacheService implements IUserCacheService {private NamedCache userCache = null; public UserCacheService() {setUserCache(CacheFactory.getCache(SystemConstants.USER_CACHE));//UserMap Listener is registered to listen user-cache operationsgetUserCache().addMapListener(new UserMapListener());} /*** Adds user to cache** @param User user*/public void addUser(User user) {getUserCache().put(user.getId(), user);}/*** Deletes user from the cache** @param String userId* @param DeleteUserProcessor processor**/public void deleteUser(String userId, DeleteUserProcessor processor) {getUserCache().invoke(userId, processor);}/*** Updates user on the cache** @param String userId* @param UpdateUserProcessor processor**/public void updateUser(String userId, UpdateUserProcessor processor) {getUserCache().invoke(userId, processor);}/*** Gets Distributed User Cache** @return NamedCache User Cache*/public NamedCache getUserCache() {return userCache;}/*** Sets User Cache** @param NamedCache userCache*/public void setUserCache(NamedCache userCache) {this.userCache = userCache;}
}

步驟12:建立USERMAPLISTENER類別

創建一個新的UserMapListener類。 該偵聽器接收分布式用戶緩存事件。

package com.otv.cache.listener;import org.apache.log4j.Logger;import com.tangosol.util.MapEvent;
import com.tangosol.util.MapListener;/*** User Map Listener** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class UserMapListener implements MapListener {private static Logger logger = Logger.getLogger(UserMapListener.class);/*** This method is invoked when an entry is deleted from the cache...** @param MapEvent me*/public void entryDeleted(MapEvent me) {logger.debug("Deleted Key = " + me.getKey() + ", Value = " + me.getOldValue());}/*** This method is invoked when an entry is inserted to the cache...** @param MapEvent me*/public void entryInserted(MapEvent me) {logger.debug("Inserted Key = " + me.getKey() + ", Value = " + me.getNewValue());}/*** This method is invoked when an entry is updated on the cache...** @param MapEvent me*/public void entryUpdated(MapEvent me) {logger.debug("Updated Key = " + me.getKey() + ", New_Value = " + me.getNewValue() + ", Old Value = " + me.getOldValue());}
}

步驟13:創建UpdateUserProcessor類

AbstractProcessor是位于com.tangosol.util.processor包下的抽象類。 它實現EntryProcessor接口。

創建UpdateUserProcessor類以處理緩存上的用戶更新操作。 當為密鑰調用UpdateUserProcessor時 ,首先在集群中找到包含該密鑰的成員。 之后,從包含相關鍵的成員中調用UpdateUserProcessor ,并更新其值(用戶對象)。 因此,減少了網絡流量。

package com.otv.user.processor;import java.io.IOException;import org.apache.log4j.Logger;import com.otv.user.User;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.InvocableMap.Entry;
import com.tangosol.util.processor.AbstractProcessor;/*** Update User Processor** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class UpdateUserProcessor extends AbstractProcessor implements PortableObject { private static Logger logger = Logger.getLogger(UpdateUserProcessor.class);private User newUser;/*** This empty constructor is added for Portable Object Format(POF).**/public UpdateUserProcessor() {}public UpdateUserProcessor(User newUser) {this.newUser = newUser;}/*** Processes a Map.Entry object.** @param Entry entry* @return Object newUser*/public Object process(Entry entry) {Object newValue = null;try {newValue = getNewUser();entry.setValue(newValue);} catch (Exception e) {logger.error("Error occured when entry was being processed!", e);}return newValue;}/*** Gets new user** @return User newUser*/public User getNewUser() {return newUser;}/*** Sets new user** @param User newUser*/public void setNewUser(User newUser) {this.newUser = newUser;}/*** Restore the contents of a user type instance by reading its state* using the specified PofReader object.** @param PofReader in*/public void readExternal(PofReader in) throws IOException {setNewUser((User) in.readObject(0));}/*** Save the contents of a POF user type instance by writing its state* using the specified PofWriter object.** @param PofWriter out*/public void writeExternal(PofWriter out) throws IOException {out.writeObject(0, getNewUser());}
}

步驟14:創建DeleteUserProcessor類別

創建DeleteUserProcessor類以處理緩存上的用戶刪除操作。 當為密鑰調用DeleteUserProcessor時 ,首先在集群中找到包含該密鑰的成員。 然后,從包含相關密鑰的成員中調用DeleteUserProcessor 。 因此,減少了網絡流量。

package com.otv.user.processor;import java.io.IOException;import org.apache.log4j.Logger;import com.otv.user.User;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.InvocableMap.Entry;
import com.tangosol.util.processor.AbstractProcessor;/*** Delete User Processor** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class DeleteUserProcessor extends AbstractProcessor implements PortableObject { private static Logger logger = Logger.getLogger(DeleteUserProcessor.class);/*** Processes a Map.Entry object.** @param Entry entry* @return Object user*/public Object process(Entry entry) {User user = null;try {user = (User) entry.getValue();entry.remove(true);} catch (Exception e) {logger.error("Error occured when entry was being processed!", e);}return user;}/*** Restore the contents of a user type instance by reading its state* using the specified PofReader object.** @param PofReader in*/public void readExternal(PofReader in) throws IOException {}/*** Save the contents of a POF user type instance by writing its state* using the specified PofWriter object.** @param PofWriter out*/public void writeExternal(PofWriter out) throws IOException {}
}

步驟15:創建CacheUpdaterTask類別

創建CacheUpdaterTask類以執行緩存操作(添加,更新和刪除)并監視緩存內容。

package com.otv.cache.updater.task;import java.util.Collection;import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;import com.otv.common.SystemConstants;
import com.otv.user.User;
import com.otv.user.cache.srv.IUserCacheService;
import com.otv.user.processor.DeleteUserProcessor;
import com.otv.user.processor.UpdateUserProcessor;/*** Cache Updater Task** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class CacheUpdaterTask implements BeanFactoryAware, Runnable {private static Logger log = Logger.getLogger(CacheUpdaterTask.class);private IUserCacheService userCacheService;private BeanFactory beanFactory;public void run() {try {while(true) {/*** Before the project is built for the first member,* this code block should be used instead of* method processRequestsOnSecondMemberOfCluster.*/processRequestsOnFirstMemberOfCluster();/*** Before the project is built for the second member,* this code block should be used instead of* method processRequestsOnFirstMemberOfCluster.*/
//    processRequestsOnSecondMemberOfCluster();}} catch (InterruptedException e) {e.printStackTrace();}}/*** Processes the cache requests on the first member of cluster...** @throws InterruptedException*/private void processRequestsOnFirstMemberOfCluster() throws InterruptedException {//Entry is added to cache...getUserCacheService().addUser(getUser("1", "Bruce", "Willis"));//Cache Entries are being printed...printCacheEntries();Thread.sleep(10000);User newUser = getUser("1", "Client", "Eastwood");//Existent Entry is updated on the cache...getUserCacheService().updateUser(newUser.getId(), new UpdateUserProcessor(newUser));//Cache Entries are being printed...printCacheEntries();Thread.sleep(10000);//Entry is deleted from cache...getUserCacheService().deleteUser(newUser.getId(), new DeleteUserProcessor());//Cache Entries are being printed...printCacheEntries();Thread.sleep(10000);}/*** Processes the cache requests on the second member of cluster...** @throws InterruptedException*/private void processRequestsOnSecondMemberOfCluster() throws InterruptedException {//Entry is added to cache...getUserCacheService().addUser(getUser("2", "Nathalie", "Portman"));Thread.sleep(15000);User newUser = getUser("2", "Sharon", "Stone");//Existent Entry is updated on the cache...getUserCacheService().updateUser(newUser.getId(), new UpdateUserProcessor(newUser));User newUser2 = getUser("1", "Maria", "Sharapova");//Existent Entry is updated on the cache...getUserCacheService().updateUser(newUser2.getId(), new UpdateUserProcessor(newUser2));Thread.sleep(15000);//Entry is deleted from cache...getUserCacheService().deleteUser(newUser.getId(), new DeleteUserProcessor());Thread.sleep(15000);}/*** Prints cache entries**/private void printCacheEntries() {Collection<User> userCollection = (Collection<User>)getUserCacheService().getUserCache().values();for(User user : userCollection) {log.debug("Cache Content : "+user);}}/*** Gets new user instance** @param String user id* @param String user name* @param String user surname* @return User user*/private User getUser(String id, String name, String surname) {User user = getNewUserInstance();user.setId(id);user.setName(name);user.setSurname(surname);return user;}/*** Gets user cache service...** @return IUserCacheService userCacheService*/public IUserCacheService getUserCacheService() {return userCacheService;}/*** Sets user cache service...** @param IUserCacheService userCacheService*/public void setUserCacheService(IUserCacheService userCacheService) {this.userCacheService = userCacheService;}/*** Gets a new instance of User Bean** @return User*/public User getNewUserInstance() {return  (User) getBeanFactory().getBean(SystemConstants.BEAN_NAME_USER);}/*** Gets bean factory** @return BeanFactory*/public BeanFactory getBeanFactory() {return beanFactory;}/*** Sets bean factory** @param BeanFactory beanFactory* @throws BeansException*/public void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}
}

步驟16:創建應用程序類

創建應用程序類以運行應用程序。

package com.otv.exe;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.otv.cache.updater.task.CacheUpdaterTask;
import com.otv.common.SystemConstants;/*** Application Class** @author  onlinetechvision.com* @since   2 Jun 2012* @version 1.0.0**/
public class Application {/*** Starts the application** @param  String[] args**/public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext(SystemConstants.APPLICATION_CONTEXT_FILE_NAME);CacheUpdaterTask cacheUpdaterTask = (CacheUpdaterTask) context.getBean(SystemConstants.BEAN_NAME_CACHE_UPDATER_TASK);Thread cacheUpdater = new Thread(cacheUpdaterTask);cacheUpdater.start();}
}

步驟17:建立專案

在構建OTV_Spring_Coherence_With_Processor_and_POF項目之后,將創建OTV_Spring_Coherence-0.0.1-SNAPSHOT.jar
請注意,集群成員的Coherence配置不同,因此應為每個成員分別構建項目。

步驟18:在集群的第一個成員上運行項目

在集群成員上運行了已創建的OTV_Spring_Coherence-0.0.1-SNAPSHOT.jar文件后,以下輸出日志將顯示在第一個成員的控制臺上:

--After A new cluster is created and First Member joins the cluster, a new entry is added to the cache.
02.06.2012 14:21:45 DEBUG (UserMapListener.java:33) - Inserted Key = 1, Value = Id : 1, Name : Bruce, Surname : Willis
02.06.2012 14:21:45 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 1, Name : Bruce, Surname : Willis
.......
--After Second Member joins the cluster, a new entry is added to the cache.
02.06.2012 14:21:45 DEBUG (UserMapListener.java:33) - Inserted Key = 2, Value = Id : 2, Name : Nathalie, Surname : Portman
.......
--Cache operations go on both first and second members of the cluster:
02.06.2012 14:21:55 DEBUG (UserMapListener.java:42) - Updated Key = 1, New_Value = Id : 1, Name : Client, Surname : Eastwood,Old Value = Id : 1, Name : Bruce, Surname : Willis02.06.2012 14:21:55 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 2, Name : Nathalie, Surname : Portman
02.06.2012 14:21:55 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 1, Name : Client, Surname : Eastwood02.06.2012 14:22:00 DEBUG (UserMapListener.java:42) - Updated Key = 2, New_Value = Id : 2, Name : Sharon, Surname : Stone,Old Value = Id : 2, Name : Nathalie, Surname : Portman02.06.2012 14:22:00 DEBUG (UserMapListener.java:42) - Updated Key = 1, New_Value = Id : 1, Name : Maria, Surname : Sharapova,Old Value = Id : 1, Name : Client, Surname : Eastwood02.06.2012 14:22:05 DEBUG (UserMapListener.java:24) - Deleted Key = 1, Value = Id : 1, Name : Maria, Surname : Sharapova
02.06.2012 14:22:05 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 2, Name : Sharon, Surname : Stone
02.06.2012 14:22:15 DEBUG (UserMapListener.java:24) - Deleted Key = 2, Value = Id : 2, Name : Sharon, Surname : Stone
02.06.2012 14:22:15 DEBUG (UserMapListener.java:33) - Inserted Key = 1, Value = Id : 1, Name : Bruce, Surname : Willis
02.06.2012 14:22:15 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 1, Name : Bruce, Surname : Willis

步驟19:下載

OTV_Spring_Coherence_With_Processor_and_POF

進一步閱讀:

連貫地執行交易
在一致性中使用可移植對象格式
Spring Framework參考3.x

參考: Online Technology Vision博客上來自JCG合作伙伴 Eren Avsarogullari的Oracle Coherence中的EntryProcessor和PortableObject特性如何分發Spring Bean 。


翻譯自: https://www.javacodegeeks.com/2012/06/distribute-spring-beans-in-oracle.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372404.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372404.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

postman測試實例--斷言

讓我們來看看postman測試的一些例子。 其中大部分是作為內部postman片段。 大多數測試是為單行的JavaScript語句一樣簡單。 只要你想一個請求&#xff0c;你可以有很多的測試。注意&#xff1a;一個響應已從服務器接收后測試腳本運行。測試實例1.設置環境變量 postman.setEnvir…

python實現單例模式的幾種方式_基于Python中單例模式的幾種實現方式及優化詳解...

單例模式單例模式(Singleton Pattern)是一種常用的軟件設計模式&#xff0c;該模式的主要目的是確保某一個類只有一個實例存在。當你希望在整個系統中&#xff0c;某個類只能出現一個實例時&#xff0c;單例對象就能派上用場。比如&#xff0c;某個服務器程序的配置信息存放在一…

android-鈴聲的設置與播放

在android系統中&#xff0c;不同鈴聲存放的鈴聲路徑&#xff1a;/system/media/audio/ringtones 來電鈴聲/system/media/audio/notifications 短信通知鈴聲/system/media/audio/alarms 鬧鐘鈴聲鈴聲的設置&#xff1a;import java.io.File; import andr…

Apache Commons SCXML:有限狀態機實現

本文提到有限狀態機&#xff08;FSM&#xff09;&#xff0c;SCXML&#xff08;狀態圖可擴展標記語言&#xff09;和Apache Common的SCXML庫。 本文還提供了基本的ATM有限狀態機示例代碼。 有限狀態機&#xff1a; 您可能還記得計算機科學課程中的有限狀態機。 FSM用于設計計算…

第二十章、分離應用程序邏輯并處理事件

理解委托 委托是對方法的引用。&#xff08;之所以稱為委托&#xff0c;是因為一旦被調用&#xff0c;就將具體的處理“委托”給引用的方法&#xff09; 委托對象引用了方法&#xff0c;和將int賦值給int變量一樣&#xff0c;是將方法引用賦給委托對象。 Processor p new Proc…

pymol怎么做底物口袋表面_怎么從文獻中發掘一篇新文章?

本文來自微信公眾號&#xff1a;X-MOLNews可能你的導師也曾說過這樣的話——盯著Nature、Science級別的文章做&#xff0c;可能最終會中十分的文章&#xff1b;如果盯著十分的文章做&#xff0c;可能最終發出來也就五六分&#xff1b;但如果就為了發個文章混畢業&#xff0c;很…

如何分析線程轉儲– IBM VM

本文是我們的線程轉儲分析系列的第4部分&#xff0c;它將為您概述什么是IBM VM的JVM線程轉儲以及您將找到的不同線程和數據點。 您將看到和學習??到&#xff0c;IBM VM Thread Dump格式是不同的&#xff0c;但是提供了更多現成的故障排除數據。 在這一點上&#xff0c;您應該…

VMware vSphere克隆虛擬機

參考資料&#xff1a;http://blog.csdn.net/shen_jz2012/article/details/484167711. 首先將你所要克隆的虛擬機關掉2. 選擇你的ESXI服務器選中"配置"&#xff0c;然后選中存儲器右鍵你的存儲介質&#xff0c;比如我的是datastore1&#xff0c;選擇“瀏覽數據存儲”。…

將本地jar包倒入maven項目類庫中

有兩種方法&#xff1a;1.本地下載maven并配置環境變量&#xff0c;然后運行cmd控制臺輸入 mvn install:install-file -Dfile本地jar路徑 -DgroupId -DartifactId -Dpackagingjar -Dversion -DgeneratePomtrue. 2.直接在pom.xml中對應的依賴下面添加<scope>system&l…

Spring和JSF集成:分頁

處理大型數據集時&#xff0c;通常需要以分頁格式顯示數據。 分頁是一個有趣的問題&#xff0c;因為它傾向于跨越應用程序的所有層&#xff0c;從視圖層通過應用程序服務一直到對數據庫的原始調用。 在獲取分頁數據時&#xff0c;有一些非常好的解決方案。 如果您使用的是JPA&a…

三重積分平均值_直角坐標系下的三重積分的幾何可視化解釋圖解高等數學

12.4 直角坐標系下的三重積分三重積分假設 F(x,y,z) 為一個空間有界閉區域 D 上的函數. D 為下面立體橢球所占區域. 將空間區域分割成小長方塊. 體積記為 ΔVk, 其長寬高分別為Δxk, Δyk, Δzk , 并有下列的求和式:觀察下面動畫, 當空間不斷分割, 每個小方塊的體積 ΔVk 不斷變…

最短網絡Agri-Net

【例4-11】、最短網絡Agri-Net【問題描述】農民約翰被選為他們鎮的鎮長&#xff01;他其中一個競選承諾就是在鎮上建立起互聯網&#xff0c;并連接到所有的農場。當然&#xff0c;他需要你的幫助。約翰已經給他的農場安排了一條高速的網絡線路&#xff0c;他想把這條線路共享給…

cors-synchronous-requests-not-working-in-firefox

http://stackoverflow.com/questions/16668386/cors-synchronous-requests-not-working-in-firefox轉載于:https://www.cnblogs.com/diyunpeng/p/5829594.html

硬盤接口協議

硬盤是電腦主要的存儲媒介之一&#xff0c;由一個或者多個鋁制或者玻璃制的碟片組成。碟片外覆蓋有鐵磁性材料。硬盤有固態硬盤&#xff08;SSD 盤&#xff0c;新式硬盤&#xff09;、機械硬盤&#xff08;HDD 傳統硬盤&#xff09;、混合硬盤&#xff08;HHD 一塊基于傳統機械…

圖的表示

Python 數據結構與算法——圖&#xff08;Graph&#xff09; 1. 鄰接矩陣 vs 鄰接表&#xff08;壓縮的鄰接矩陣&#xff09; 鄰接矩陣的缺點是&#xff1a; 空間占用與結點數的平方成正比&#xff0c;可能帶來很大的浪費&#xff1b;鄰接矩陣不容易增加新的結點&#xff0c;不…

在Java Web應用程序中阻止CSRF

跨站點請求偽造攻擊&#xff08;CSRF&#xff09;在Web應用程序中非常常見&#xff0c;如果允許&#xff0c;可能會造成重大危害。 如果您從未聽說過CSRF&#xff0c;建議您查看有關它的OWASP頁面 。 幸運的是&#xff0c;阻止CSRF攻擊非常簡單&#xff0c;我將向您展示它們的工…

windows命令行無法啟動redis_windows系統安裝redis

1、下載最新redis https://github.com/MicrosoftArchive/redis/releases我選擇下載msi版本的2.雙擊下載包安裝3.設置redis環境變量&#xff0c;把redis路徑配置到系統變量path值中4啟動redis&#xff0c;cmd進入安裝好redis文件夾 輸入&#xff1a;如果redis啟動出錯Creating S…

SQL Server 篩選時間區間

一、SQL直接判斷 select * from login where pass>2013/03/25 and pass < 2017/04/24 二、DATEDIFF() 函數返回兩個日期之間的時間 --語法 DATEDIFF(datepart,startdate,enddate) --開始時間 startdate --結束時間 enddate --datepart datepart縮寫年yy, yyyy季度qq, …

OpenShift Express Web管理控制臺:入門

本周&#xff0c; 最新版本的OpenShift為已經很棒的PaaS Cloud提供商帶來了兩個非常好的功能。 首先&#xff0c;JBoss AS已從7.0升級到7.1&#xff0c;并且所有新的Express Web Management Console已作為預覽發布。 在本文中&#xff0c;我們將研究如何使用此新控制臺&#xf…

Linux-IP地址后邊加個/8(16,24,32)是什么意思?

是掩碼的位數 A類IP地址的默認子網掩碼為255.0.0.0&#xff08;由于255相當于二進制的8位1&#xff0c;所以也縮寫成“/8”&#xff0c;表示網絡號占了8位&#xff09;; B類的為255.255.0.0&#xff08;/16&#xff09;; C類的為255.255.255.0(/24) /30就是255…