From 17e56dda1884b50bbe098441ea70fb9f9bc5ca9d Mon Sep 17 00:00:00 2001 From: Vedran Pavic Date: Fri, 3 Nov 2017 07:11:00 +0100 Subject: [PATCH] Polish configuration classes --- .../web/http/EnableRedisHttpSession.java | 34 ++++------ .../http/RedisHttpSessionConfiguration.java | 16 ++--- .../web/server/EnableRedisWebSession.java | 43 ++++++------ .../server/RedisWebSessionConfiguration.java | 30 ++++----- .../web/http/EnableHazelcastHttpSession.java | 45 +++++++------ .../HazelcastHttpSessionConfiguration.java | 65 ++++++++++++------- ...azelcastHttpSessionConfigurationTests.java | 6 +- .../web/http/EnableJdbcHttpSession.java | 24 ++++--- .../http/JdbcHttpSessionConfiguration.java | 29 +++++---- 9 files changed, 155 insertions(+), 137 deletions(-) diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java index f43f6c30..ad15d056 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java @@ -25,16 +25,19 @@ import java.lang.annotation.Target; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.session.MapSession; +import org.springframework.session.Session; import org.springframework.session.SessionRepository; import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; import org.springframework.session.data.redis.RedisFlushMode; import org.springframework.session.data.redis.RedisOperationsSessionRepository; +import org.springframework.session.web.http.SessionRepositoryFilter; /** * Add this annotation to an {@code @Configuration} class to expose the - * SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by - * Redis. In order to leverage the annotation, a single {@link RedisConnectionFactory} - * must be provided. For example: + * {@link SessionRepositoryFilter} as a bean named {@code springSessionRepositoryFilter} + * and backed by Redis. In order to leverage the annotation, a single + * {@link RedisConnectionFactory} must be provided. For example: * *
  * @Configuration
@@ -42,7 +45,7 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository;
  * public class RedisHttpSessionConfig {
  *
  *     @Bean
- *     public LettuceConnectionFactory connectionFactory() {
+ *     public LettuceConnectionFactory redisConnectionFactory() {
  *         return new LettuceConnectionFactory();
  *     }
  *
@@ -68,37 +71,27 @@ public @interface EnableRedisHttpSession {
 	 * This should be a non-negative integer.
 	 * @return the seconds a session can be inactive before expiring
 	 */
-	int maxInactiveIntervalInSeconds() default 1800;
+	int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
 
 	/**
-	 * 

* Defines a unique namespace for keys. The value is used to isolate sessions by * changing the prefix from default {@code spring:session:} to * {@code :}. - *

- * *

* For example, if you had an application named "Application A" that needed to keep * the sessions isolated from "Application B" you could set two different values for * the applications and they could function within the same Redis instance. - *

- * * @return the unique namespace for keys */ String redisNamespace() default RedisOperationsSessionRepository.DEFAULT_NAMESPACE; /** + * Flush mode for the Redis sessions. The default is {@code ON_SAVE} which only + * updates the backing Redis when {@link SessionRepository#save(Session)} is invoked. + * In a web environment this happens just before the HTTP response is committed. *

- * Sets the flush mode for the Redis sessions. The default is ON_SAVE which only - * updates the backing Redis when - * {@link SessionRepository#save(org.springframework.session.Session)} is invoked. In - * a web environment this happens just before the HTTP response is committed. - *

- *

- * Setting the value to IMMEDIATE will ensure that the any updates to the Session are - * immediately written to the Redis instance. - *

- * + * Setting the value to {@code IMMEDIATE} will ensure that the any updates to the + * Session are immediately written to the Redis instance. * @return the {@link RedisFlushMode} to use * @since 1.1 */ @@ -107,6 +100,7 @@ public @interface EnableRedisHttpSession { /** * The cron expression for expired session cleanup job. By default runs every minute. * @return the session cleanup cron expression + * @since 2.0.0 */ String cleanupCron() default RedisHttpSessionConfiguration.DEFAULT_CLEANUP_CRON; diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java index af7d42ba..55a62a8f 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java @@ -44,6 +44,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.config.ScheduledTaskRegistrar; +import org.springframework.session.MapSession; import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration; import org.springframework.session.data.redis.RedisFlushMode; import org.springframework.session.data.redis.RedisOperationsSessionRepository; @@ -57,7 +58,7 @@ import org.springframework.util.StringValueResolver; /** * Exposes the {@link SessionRepositoryFilter} as a bean named - * "springSessionRepositoryFilter". In order to use this a single + * {@code springSessionRepositoryFilter}. In order to use this a single * {@link RedisConnectionFactory} must be exposed as a Bean. * * @author Rob Winch @@ -73,9 +74,9 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio static final String DEFAULT_CLEANUP_CRON = "0 * * * * *"; - private Integer maxInactiveIntervalInSeconds = 1800; + private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - private String redisNamespace = ""; + private String redisNamespace = RedisOperationsSessionRepository.DEFAULT_NAMESPACE; private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE; @@ -115,8 +116,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio } @Bean - public RedisMessageListenerContainer redisMessageListenerContainer( - RedisOperationsSessionRepository messageListener) { + public RedisMessageListenerContainer redisMessageListenerContainer() { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(this.redisConnectionFactory); if (this.redisTaskExecutor != null) { @@ -125,12 +125,12 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio if (this.redisSubscriptionExecutor != null) { container.setSubscriptionExecutor(this.redisSubscriptionExecutor); } - container.addMessageListener(messageListener, + container.addMessageListener(sessionRepository(), Arrays.asList(new PatternTopic("__keyevent@*:del"), new PatternTopic("__keyevent@*:expired"))); - container.addMessageListener(messageListener, + container.addMessageListener(sessionRepository(), Collections.singletonList(new PatternTopic( - messageListener.getSessionCreatedChannelPrefix() + "*"))); + sessionRepository().getSessionCreatedChannelPrefix() + "*"))); return container; } diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/EnableRedisWebSession.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/EnableRedisWebSession.java index 8f4bf9f7..11c76e06 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/EnableRedisWebSession.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/EnableRedisWebSession.java @@ -17,24 +17,29 @@ package org.springframework.session.data.redis.config.annotation.web.server; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory; +import org.springframework.session.MapSession; import org.springframework.session.ReactiveSessionRepository; import org.springframework.session.Session; import org.springframework.session.config.annotation.web.server.EnableSpringWebSession; import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository; import org.springframework.session.data.redis.RedisFlushMode; +import org.springframework.web.server.session.WebSessionManager; /** * Add this annotation to an {@code @Configuration} class to expose the - * {@link org.springframework.web.server.session.WebSessionManager} as a bean named - * {@code webSessionManager} and backed by Reactive Redis. In order to leverage the - * annotation, a single {@link ReactiveRedisConnectionFactory} must be provided. For - * example:
+ * {@link WebSessionManager} as a bean named {@code webSessionManager} and backed by
+ * Reactive Redis. In order to leverage the annotation, a single
+ * {@link ReactiveRedisConnectionFactory} must be provided. For example:
+ *
+ * 
  * @Configuration
  * @EnableRedisWebSession
  * public class RedisWebSessionConfig {
@@ -47,52 +52,46 @@ import org.springframework.session.data.redis.RedisFlushMode;
  * }
  * 
* - * More advanced configurations can extend {@link RedisWebSessionConfiguration} - * instead. + * More advanced configurations can extend {@link RedisWebSessionConfiguration} instead. * * @author Vedran Pavic * @since 2.0.0 * @see EnableSpringWebSession */ -@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) -@Target({ java.lang.annotation.ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) @Documented @Import(RedisWebSessionConfiguration.class) @Configuration public @interface EnableRedisWebSession { - int maxInactiveIntervalInSeconds() default 1800; + /** + * The session timeout in seconds. By default, it is set to 1800 seconds (30 minutes). + * This should be a non-negative integer. + * @return the seconds a session can be inactive before expiring + */ + int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; /** - *

* Defines a unique namespace for keys. The value is used to isolate sessions by * changing the prefix from default {@code spring:session:} to * {@code :}. - *

- * *

* For example, if you had an application named "Application A" that needed to keep * the sessions isolated from "Application B" you could set two different values for * the applications and they could function within the same Redis instance. - *

- * * @return the unique namespace for keys */ String redisNamespace() default ReactiveRedisOperationsSessionRepository.DEFAULT_NAMESPACE; /** - *

- * Sets the flush mode for the Redis sessions. The default is ON_SAVE which only + * Flush mode for the Redis sessions. The default is {@code ON_SAVE} which only * updates the backing Redis when {@link ReactiveSessionRepository#save(Session)} is * invoked. In a web environment this happens just before the HTTP response is * committed. - *

- * *

- * Setting the value to IMMEDIATE will ensure that the any updates to the Session are - * immediately written to the Redis instance. - *

- * + * Setting the value to {@code IMMEDIATE} will ensure that the any updates to the + * Session are immediately written to the Redis instance. * @return the {@link RedisFlushMode} to use */ RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE; diff --git a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java index bb25f932..da69e153 100644 --- a/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java +++ b/spring-session-data-redis/src/main/java/org/springframework/session/data/redis/config/annotation/web/server/RedisWebSessionConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; +import org.springframework.session.MapSession; import org.springframework.session.config.annotation.web.server.SpringWebSessionConfiguration; import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository; import org.springframework.session.data.redis.RedisFlushMode; @@ -58,9 +59,9 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration private static final RedisSerializer valueSerializer = new JdkSerializationRedisSerializer(); - private Integer maxInactiveIntervalInSeconds = 1800; + private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - private String redisNamespace = ""; + private String redisNamespace = ReactiveRedisOperationsSessionRepository.DEFAULT_NAMESPACE; private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE; @@ -74,13 +75,10 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration createDefaultTemplate(this.redisConnectionFactory)); sessionRepository .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); - if (StringUtils.hasText(this.redisNamespace)) { sessionRepository.setRedisKeyNamespace(this.redisNamespace); } - sessionRepository.setRedisFlushMode(this.redisFlushMode); - return sessionRepository; } @@ -116,20 +114,17 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration @Override public void setImportMetadata(AnnotationMetadata importMetadata) { - Map enableAttrMap = importMetadata + Map attributeMap = importMetadata .getAnnotationAttributes(EnableRedisWebSession.class.getName()); - AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); - - if (enableAttrs != null) { - this.maxInactiveIntervalInSeconds = enableAttrs - .getNumber("maxInactiveIntervalInSeconds"); - String redisNamespaceValue = enableAttrs.getString("redisNamespace"); - if (StringUtils.hasText(redisNamespaceValue)) { - this.redisNamespace = this.embeddedValueResolver - .resolveStringValue(redisNamespaceValue); - } - this.redisFlushMode = enableAttrs.getEnum("redisFlushMode"); + AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap); + this.maxInactiveIntervalInSeconds = attributes + .getNumber("maxInactiveIntervalInSeconds"); + String redisNamespaceValue = attributes.getString("redisNamespace"); + if (StringUtils.hasText(redisNamespaceValue)) { + this.redisNamespace = this.embeddedValueResolver + .resolveStringValue(redisNamespaceValue); } + this.redisFlushMode = attributes.getEnum("redisFlushMode"); } private static ReactiveRedisTemplate createDefaultTemplate( @@ -137,7 +132,6 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration RedisSerializationContext serializationContext = RedisSerializationContext .newSerializationContext(valueSerializer) .key(keySerializer).hashKey(keySerializer).build(); - return new ReactiveRedisTemplate<>(connectionFactory, serializationContext); } diff --git a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java index 14db3669..9914163a 100644 --- a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java +++ b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/EnableHazelcastHttpSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,34 +17,41 @@ package org.springframework.session.hazelcast.config.annotation.web.http; import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import com.hazelcast.core.HazelcastInstance; + import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.session.MapSession; +import org.springframework.session.Session; import org.springframework.session.SessionRepository; import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; import org.springframework.session.hazelcast.HazelcastFlushMode; +import org.springframework.session.web.http.SessionRepositoryFilter; /** - * Add this annotation to a {@code @Configuration} class to expose the - * SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by - * Hazelcast. In order to leverage the annotation, a single HazelcastInstance must be - * provided. For example:
- * 
- * {@literal @Configuration}
- * {@literal @EnableHazelcastHttpSession}
+ * Add this annotation to an {@code @Configuration} class to expose the
+ * {@link SessionRepositoryFilter} as a bean named {@code springSessionRepositoryFilter}
+ * and backed by Hazelcast. In order to leverage the annotation, a single
+ * {@link HazelcastInstance} must be provided. For example:
+ *
+ * 
+ * @Configuration
+ * @EnableHazelcastHttpSession
  * public class HazelcastHttpSessionConfig {
  *
- *     {@literal @Bean}
+ *     @Bean
  *     public HazelcastInstance embeddedHazelcast() {
  *         Config hazelcastConfig = new Config();
  *         return Hazelcast.newHazelcastInstance(hazelcastConfig);
  *     }
  *
  * }
- *  
+ *
* * More advanced configurations can extend {@link HazelcastHttpSessionConfiguration} * instead. @@ -54,33 +61,33 @@ import org.springframework.session.hazelcast.HazelcastFlushMode; * @since 1.1 * @see EnableSpringHttpSession */ -@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) -@Target({ java.lang.annotation.ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) @Documented @Import(HazelcastHttpSessionConfiguration.class) @Configuration public @interface EnableHazelcastHttpSession { /** - * This is the session timeout in seconds. By default, it is set to 1800 seconds (30 - * minutes). This should be a non-negative integer. - * + * The session timeout in seconds. By default, it is set to 1800 seconds (30 minutes). + * This should be a non-negative integer. * @return the seconds a session can be inactive before expiring */ int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; /** * This is the name of the Map that will be used in Hazelcast to store the session - * data. Default is {@link HazelcastHttpSessionConfiguration#DEFAULT_SESSION_MAP_NAME}. + * data. Default is + * {@link HazelcastHttpSessionConfiguration#DEFAULT_SESSION_MAP_NAME}. * @return the name of the Map to store the sessions in Hazelcast */ String sessionMapName() default HazelcastHttpSessionConfiguration.DEFAULT_SESSION_MAP_NAME; /** * Flush mode for the Hazelcast sessions. The default is {@code ON_SAVE} which only - * updates the backing Hazelcast when - * {@link SessionRepository#save(org.springframework.session.Session)} is invoked. In - * a web environment this happens just before the HTTP response is committed. + * updates the backing Hazelcast when {@link SessionRepository#save(Session)} is + * invoked. In a web environment this happens just before the HTTP response is + * committed. *

* Setting the value to {@code IMMEDIATE} will ensure that the any updates to the * Session are immediately written to the Hazelcast instance. diff --git a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java index 68e60d28..e4acc554 100644 --- a/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java +++ b/spring-session-hazelcast/src/main/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfiguration.java @@ -22,6 +22,7 @@ import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -34,10 +35,11 @@ import org.springframework.session.hazelcast.HazelcastFlushMode; import org.springframework.session.hazelcast.HazelcastSessionRepository; import org.springframework.session.hazelcast.config.annotation.SpringSessionHazelcastInstance; import org.springframework.session.web.http.SessionRepositoryFilter; +import org.springframework.util.StringUtils; /** * Exposes the {@link SessionRepositoryFilter} as a bean named - * "springSessionRepositoryFilter". In order to use this a single + * {@code springSessionRepositoryFilter}. In order to use this a single * {@link HazelcastInstance} must be exposed as a Bean. * * @author Tommy Ludwig @@ -57,38 +59,23 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur private HazelcastFlushMode hazelcastFlushMode = HazelcastFlushMode.ON_SAVE; + private HazelcastInstance hazelcastInstance; + + private ApplicationEventPublisher applicationEventPublisher; + @Bean - public HazelcastSessionRepository sessionRepository( - @SpringSessionHazelcastInstance ObjectProvider springSessionHazelcastInstance, - ObjectProvider hazelcastInstance, - ApplicationEventPublisher eventPublisher) { - HazelcastInstance hazelcastInstanceToUse = springSessionHazelcastInstance - .getIfAvailable(); - if (hazelcastInstanceToUse == null) { - hazelcastInstanceToUse = hazelcastInstance.getObject(); - } - IMap sessions = hazelcastInstanceToUse + public HazelcastSessionRepository sessionRepository() { + IMap sessions = this.hazelcastInstance .getMap(this.sessionMapName); HazelcastSessionRepository sessionRepository = new HazelcastSessionRepository( sessions); - sessionRepository.setApplicationEventPublisher(eventPublisher); + sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher); sessionRepository .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); sessionRepository.setHazelcastFlushMode(this.hazelcastFlushMode); return sessionRepository; } - @Override - public void setImportMetadata(AnnotationMetadata importMetadata) { - Map enableAttrMap = importMetadata - .getAnnotationAttributes(EnableHazelcastHttpSession.class.getName()); - AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); - setMaxInactiveIntervalInSeconds( - enableAttrs.getNumber("maxInactiveIntervalInSeconds")); - setSessionMapName(enableAttrs.getString("sessionMapName")); - setHazelcastFlushMode(enableAttrs.getEnum("hazelcastFlushMode")); - } - public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; } @@ -101,4 +88,36 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur this.hazelcastFlushMode = hazelcastFlushMode; } + @Autowired + public void setHazelcastInstance( + @SpringSessionHazelcastInstance ObjectProvider springSessionHazelcastInstance, + ObjectProvider hazelcastInstance) { + HazelcastInstance hazelcastInstanceToUse = springSessionHazelcastInstance + .getIfAvailable(); + if (hazelcastInstanceToUse == null) { + hazelcastInstanceToUse = hazelcastInstance.getObject(); + } + this.hazelcastInstance = hazelcastInstanceToUse; + } + + @Autowired + public void setApplicationEventPublisher( + ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + + @Override + public void setImportMetadata(AnnotationMetadata importMetadata) { + Map attributeMap = importMetadata + .getAnnotationAttributes(EnableHazelcastHttpSession.class.getName()); + AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap); + this.maxInactiveIntervalInSeconds = + attributes.getNumber("maxInactiveIntervalInSeconds"); + String sessionMapNameValue = attributes.getString("sessionMapName"); + if (StringUtils.hasText(sessionMapNameValue)) { + this.sessionMapName = sessionMapNameValue; + } + this.hazelcastFlushMode = attributes.getEnum("hazelcastFlushMode"); + } + } diff --git a/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfigurationTests.java b/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfigurationTests.java index eac49839..80ffdfc1 100644 --- a/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfigurationTests.java +++ b/spring-session-hazelcast/src/test/java/org/springframework/session/hazelcast/config/annotation/web/http/HazelcastHttpSessionConfigurationTests.java @@ -204,14 +204,14 @@ public class HazelcastHttpSessionConfigurationTests { HazelcastInstance.class); assertThat(repository).isNotNull(); assertThat(hazelcastInstance).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "sessions")).isEqualTo( - NamedHazelcastInstanceConfiguration.hazelcastInstanceSessions); + assertThat(ReflectionTestUtils.getField(repository, "sessions")) + .isEqualTo(NamedHazelcastInstanceConfiguration.hazelcastInstanceSessions); } @Test public void multipleDataSourceConfiguration() { this.thrown.expect(BeanCreationException.class); - this.thrown.expectMessage("sessionRepository"); + this.thrown.expectMessage("expected single matching bean but found 2"); registerAndRefresh(MultipleHazelcastInstanceConfiguration.class); } diff --git a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/EnableJdbcHttpSession.java b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/EnableJdbcHttpSession.java index 0de8dcb8..99d39247 100644 --- a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/EnableJdbcHttpSession.java +++ b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/EnableJdbcHttpSession.java @@ -22,17 +22,20 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import javax.sql.DataSource; + import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.session.MapSession; import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession; import org.springframework.session.jdbc.JdbcOperationsSessionRepository; +import org.springframework.session.web.http.SessionRepositoryFilter; /** * Add this annotation to an {@code @Configuration} class to expose the - * SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by a - * relational database. In order to leverage the annotation, a single - * {@link javax.sql.DataSource} must be provided. For example: + * {@link SessionRepositoryFilter} as a bean named {@code springSessionRepositoryFilter} + * and backed by a relational database. In order to leverage the annotation, a single + * {@link DataSource} must be provided. For example: * *

  * @Configuration
@@ -73,22 +76,23 @@ import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
 @Configuration
 public @interface EnableJdbcHttpSession {
 
+	/**
+	 * The session timeout in seconds. By default, it is set to 1800 seconds (30 minutes).
+	 * This should be a non-negative integer.
+	 * @return the seconds a session can be inactive before expiring
+	 */
+	int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
+
 	/**
 	 * The name of database table used by Spring Session to store sessions.
 	 * @return the database table name
 	 */
 	String tableName() default JdbcOperationsSessionRepository.DEFAULT_TABLE_NAME;
 
-	/**
-	 * The session timeout in seconds. By default, it is set to 1800 seconds (30
-	 * minutes). This should be a non-negative integer.
-	 * @return the seconds a session can be inactive before expiring
-	 */
-	int maxInactiveIntervalInSeconds() default MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
-
 	/**
 	 * The cron expression for expired session cleanup job. By default runs every minute.
 	 * @return the session cleanup cron expression
+	 * @since 2.0.0
 	 */
 	String cleanupCron() default JdbcHttpSessionConfiguration.DEFAULT_CLEANUP_CRON;
 
diff --git a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java
index 584d98f2..8a986161 100644
--- a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java
+++ b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java
@@ -42,17 +42,18 @@ import org.springframework.session.MapSession;
 import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
 import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
 import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
+import org.springframework.session.web.http.SessionRepositoryFilter;
 import org.springframework.transaction.PlatformTransactionManager;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringValueResolver;
 
 /**
- * Spring @Configuration class used to configure and initialize a JDBC based HttpSession
- * provider implementation in Spring Session.
+ * Spring {@code @Configuration} class used to configure and initialize a JDBC based
+ * {@code HttpSession} provider implementation in Spring Session.
  * 

- * Exposes the {@link org.springframework.session.web.http.SessionRepositoryFilter} as a - * bean named "springSessionRepositoryFilter". In order to use this a single - * {@link DataSource} must be exposed as a Bean. + * Exposes the {@link SessionRepositoryFilter} as a bean named + * {@code springSessionRepositoryFilter}. In order to use this a single {@link DataSource} + * must be exposed as a Bean. * * @author Vedran Pavic * @author EddĂș MelĂ©ndez @@ -67,10 +68,10 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration static final String DEFAULT_CLEANUP_CRON = "0 * * * * *"; - private String tableName = JdbcOperationsSessionRepository.DEFAULT_TABLE_NAME; - private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; + private String tableName = JdbcOperationsSessionRepository.DEFAULT_TABLE_NAME; + private String cleanupCron = DEFAULT_CLEANUP_CRON; private DataSource dataSource; @@ -112,14 +113,14 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration return sessionRepository; } - public void setTableName(String tableName) { - this.tableName = tableName; - } - public void setMaxInactiveIntervalInSeconds(Integer maxInactiveIntervalInSeconds) { this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; } + public void setTableName(String tableName) { + this.tableName = tableName; + } + public void setCleanupCron(String cleanupCron) { this.cleanupCron = cleanupCron; } @@ -173,16 +174,16 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration Map attributeMap = importMetadata .getAnnotationAttributes(EnableJdbcHttpSession.class.getName()); AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap); + this.maxInactiveIntervalInSeconds = attributes + .getNumber("maxInactiveIntervalInSeconds"); String tableNameValue = attributes.getString("tableName"); if (StringUtils.hasText(tableNameValue)) { this.tableName = this.embeddedValueResolver .resolveStringValue(tableNameValue); } - this.maxInactiveIntervalInSeconds = attributes - .getNumber("maxInactiveIntervalInSeconds"); String cleanupCron = attributes.getString("cleanupCron"); if (StringUtils.hasText(cleanupCron)) { - this.cleanupCron = this.embeddedValueResolver.resolveStringValue(cleanupCron); + this.cleanupCron = cleanupCron; } }