diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java index d2914503..9b9c1692 100644 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java @@ -55,7 +55,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.session.ExpiringSession; import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.Session; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; +import org.springframework.session.SessionRepository; import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; import org.springframework.session.events.SessionCreatedEvent; import org.springframework.session.events.SessionDeletedEvent; @@ -65,18 +65,20 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * AbstractGemFireOperationsSessionRepository is an abstract base class encapsulating - * functionality common to all implementations that support SessionRepository operations - * backed by GemFire. + * AbstractGemFireOperationsSessionRepository is an abstract base class encapsulating functionality + * common to all implementations that support {@link SessionRepository} operations backed by GemFire. * * @author John Blum * @since 1.1.0 - * @see EnableGemFireHttpSession + * @see org.springframework.beans.factory.InitializingBean + * @see org.springframework.context.ApplicationEventPublisherAware + * @see org.springframework.session.ExpiringSession + * @see org.springframework.session.FindByIndexNameSessionRepository + * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession + * @see com.gemstone.gemfire.cache.util.CacheListenerAdapter */ -public abstract class AbstractGemFireOperationsSessionRepository - extends CacheListenerAdapter - implements InitializingBean, FindByIndexNameSessionRepository, - ApplicationEventPublisherAware { +public abstract class AbstractGemFireOperationsSessionRepository extends CacheListenerAdapter + implements InitializingBean, FindByIndexNameSessionRepository, ApplicationEventPublisherAware { private int maxInactiveIntervalInSeconds = GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS; @@ -125,10 +127,8 @@ public abstract class AbstractGemFireOperationsSessionRepository * publish Session-based events. * @see org.springframework.context.ApplicationEventPublisher */ - public void setApplicationEventPublisher( - ApplicationEventPublisher applicationEventPublisher) { - Assert.notNull(applicationEventPublisher, - "ApplicationEventPublisher must not be null"); + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher must not be null"); this.applicationEventPublisher = applicationEventPublisher; } @@ -190,10 +190,13 @@ public abstract class AbstractGemFireOperationsSessionRepository } /** - * Callback method during Spring bean initialization that will capture the - * fully-qualified name of the GemFire cache {@link Region} used to manage Session - * state and register this SessionRepository as a GemFire - * {@link com.gemstone.gemfire.cache.CacheListener}. + * Callback method during Spring bean initialization that will capture the fully-qualified name + * of the GemFire cache {@link Region} used to manage Session state and register this SessionRepository + * as a GemFire {@link com.gemstone.gemfire.cache.CacheListener}. + * + * Additionally, this method registers GemFire {@link Instantiator}s for the {@link GemFireSession} + * and {@link GemFireSessionAttributes} types to optimize GemFire's instantiation logic on deserialization + * using the data serialization framework when accessing the {@link Session}'s state stored in GemFire. * * @throws Exception if an error occurs during the initialization process. */ @@ -206,6 +209,20 @@ public abstract class AbstractGemFireOperationsSessionRepository this.fullyQualifiedRegionName = region.getFullPath(); region.getAttributesMutator().addCacheListener(this); + + Instantiator.register(new Instantiator(GemFireSession.class, 800813552) { + @Override + public DataSerializable newInstance() { + return new GemFireSession(); + } + }); + + Instantiator.register(new Instantiator(GemFireSessionAttributes.class, 800828008) { + @Override + public DataSerializable newInstance() { + return new GemFireSessionAttributes(); + } + }); } /* (non-Javadoc) */ @@ -229,8 +246,7 @@ public abstract class AbstractGemFireOperationsSessionRepository @Override public void afterCreate(EntryEvent event) { if (isExpiringSessionOrNull(event.getNewValue())) { - handleCreated(event.getKey().toString(), - toExpiringSession(event.getNewValue())); + handleCreated(event.getKey().toString(), toExpiringSession(event.getNewValue())); } } @@ -244,8 +260,7 @@ public abstract class AbstractGemFireOperationsSessionRepository */ @Override public void afterDestroy(EntryEvent event) { - handleDestroyed(event.getKey().toString(), - toExpiringSession(event.getOldValue())); + handleDestroyed(event.getKey().toString(), toExpiringSession(event.getOldValue())); } /** @@ -329,17 +344,15 @@ public abstract class AbstractGemFireOperationsSessionRepository getApplicationEventPublisher().publishEvent(event); } catch (Throwable t) { - this.logger.error( - String.format("error occurred publishing event (%1$s)", event), t); + this.logger.error(String.format("error occurred publishing event (%1$s)", event), t); } } /** - * GemFireSession is a GemFire representation model of a Spring - * {@link ExpiringSession} for storing and accessing Session state information in - * GemFire. This class implements GemFire's {@link DataSerializable} interface to - * better handle replication of Session information across the GemFire cluster. - * + * GemFireSession is a GemFire representation model of a Spring {@link ExpiringSession} + * that stores and manages Session state information in GemFire. This class implements + * GemFire's {@link DataSerializable} interface to better handle replication of Session + * state information across the GemFire cluster. */ @SuppressWarnings("serial") public static class GemFireSession implements Comparable, @@ -352,15 +365,6 @@ public abstract class AbstractGemFireOperationsSessionRepository protected static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; - static { - Instantiator.register(new Instantiator(GemFireSession.class, 800813552) { - @Override - public DataSerializable newInstance() { - return new GemFireSession(); - } - }); - } - private transient boolean delta = false; private int maxInactiveIntervalInSeconds; @@ -469,8 +473,7 @@ public abstract class AbstractGemFireOperationsSessionRepository /* (non-Javadoc) */ private long idleTimeout(long maxInactiveIntervalInSeconds) { - return (System.currentTimeMillis() - - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds)); + return (System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds)); } /* (non-Javadoc) */ @@ -485,8 +488,7 @@ public abstract class AbstractGemFireOperationsSessionRepository } /* (non-Javadoc) */ - public synchronized void setMaxInactiveIntervalInSeconds( - final int maxInactiveIntervalInSeconds) { + public synchronized void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { this.delta |= (this.maxInactiveIntervalInSeconds != maxInactiveIntervalInSeconds); this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; } @@ -509,8 +511,7 @@ public abstract class AbstractGemFireOperationsSessionRepository Object authentication = getAttribute(SPRING_SECURITY_CONTEXT); if (authentication != null) { - Expression expression = this.parser - .parseExpression("authentication?.name"); + Expression expression = this.parser.parseExpression("authentication?.name"); principalName = expression.getValue(authentication, String.class); } } @@ -526,8 +527,8 @@ public abstract class AbstractGemFireOperationsSessionRepository out.writeInt(getMaxInactiveIntervalInSeconds()); String principalName = getPrincipalName(); - int length = (StringUtils.hasText(principalName) ? principalName.length() - : 0); + + int length = (StringUtils.hasText(principalName) ? principalName.length() : 0); out.writeInt(length); @@ -546,8 +547,7 @@ public abstract class AbstractGemFireOperationsSessionRepository } /* (non-Javadoc) */ - public synchronized void fromData(DataInput in) - throws ClassNotFoundException, IOException { + public synchronized void fromData(DataInput in) throws ClassNotFoundException, IOException { this.id = in.readUTF(); this.creationTime = in.readLong(); setLastAccessedTime(in.readLong()); @@ -623,12 +623,10 @@ public abstract class AbstractGemFireOperationsSessionRepository /* (non-Javadoc) */ @Override public synchronized String toString() { - return String.format( - "{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s" - + ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", - getClass().getName(), getId(), toString(getCreationTime()), - toString(getLastAccessedTime()), getMaxInactiveIntervalInSeconds(), - getPrincipalName()); + return String.format("{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s" + + ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", + getClass().getName(), getId(), toString(getCreationTime()), toString(getLastAccessedTime()), + getMaxInactiveIntervalInSeconds(), getPrincipalName()); } /* (non-Javadoc) */ @@ -638,17 +636,16 @@ public abstract class AbstractGemFireOperationsSessionRepository } /** - * The GemFireSessionAttributes class is a container for Session attributes that - * implements both the {@link DataSerializable} and {@link Delta} GemFire interfaces - * for efficient storage and distribution (replication) in GemFire. Additionally, - * GemFireSessionAttributes extends {@link AbstractMap} providing {@link Map}-like - * behavior since attributes of a Session are effectively a name to value mapping. + * The GemFireSessionAttributes class is a container for Session attributes implementing + * both the {@link DataSerializable} and {@link Delta} GemFire interfaces for efficient + * storage and distribution (replication) in GemFire. Additionally, GemFireSessionAttributes + * extends {@link AbstractMap} providing {@link Map}-like behavior since attributes of a Session + * are effectively a name to value mapping. * * @see java.util.AbstractMap * @see com.gemstone.gemfire.DataSerializable * @see com.gemstone.gemfire.DataSerializer * @see com.gemstone.gemfire.Delta - * @see com.gemstone.gemfire.Instantiator */ @SuppressWarnings("serial") public static class GemFireSessionAttributes extends AbstractMap @@ -656,16 +653,6 @@ public abstract class AbstractGemFireOperationsSessionRepository protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true; - static { - Instantiator.register( - new Instantiator(GemFireSessionAttributes.class, 800828008) { - @Override - public DataSerializable newInstance() { - return new GemFireSessionAttributes(); - } - }); - } - private transient final Map sessionAttributes = new HashMap(); private transient final Map sessionAttributeDeltas = new HashMap(); @@ -685,8 +672,7 @@ public abstract class AbstractGemFireOperationsSessionRepository public void setAttribute(String attributeName, Object attributeValue) { synchronized (this.lock) { if (attributeValue != null) { - if (!attributeValue.equals( - this.sessionAttributes.put(attributeName, attributeValue))) { + if (!attributeValue.equals(this.sessionAttributes.put(attributeName, attributeValue))) { this.sessionAttributeDeltas.put(attributeName, attributeValue); } } @@ -716,8 +702,7 @@ public abstract class AbstractGemFireOperationsSessionRepository /* (non-Javadoc) */ public Set getAttributeNames() { synchronized (this.lock) { - return Collections.unmodifiableSet( - new HashSet(this.sessionAttributes.keySet())); + return Collections.unmodifiableSet(new HashSet(this.sessionAttributes.keySet())); } } @@ -733,10 +718,8 @@ public abstract class AbstractGemFireOperationsSessionRepository return new AbstractSet>() { @Override public Iterator> iterator() { - return Collections - .unmodifiableMap( - GemFireSessionAttributes.this.sessionAttributes) - .entrySet().iterator(); + return Collections.unmodifiableMap(GemFireSessionAttributes.this.sessionAttributes) + .entrySet().iterator(); } @Override @@ -759,8 +742,7 @@ public abstract class AbstractGemFireOperationsSessionRepository public void from(GemFireSessionAttributes sessionAttributes) { synchronized (this.lock) { for (String attributeName : sessionAttributes.getAttributeNames()) { - setAttribute(attributeName, - sessionAttributes.getAttribute(attributeName)); + setAttribute(attributeName, sessionAttributes.getAttribute(attributeName)); } } } @@ -812,8 +794,7 @@ public abstract class AbstractGemFireOperationsSessionRepository synchronized (this.lock) { out.writeInt(this.sessionAttributeDeltas.size()); - for (Map.Entry entry : this.sessionAttributeDeltas - .entrySet()) { + for (Map.Entry entry : this.sessionAttributeDeltas.entrySet()) { out.writeUTF(entry.getKey()); writeObject(entry.getValue(), out); } @@ -850,5 +831,4 @@ public abstract class AbstractGemFireOperationsSessionRepository return this.sessionAttributes.toString(); } } - }