Rework Spring Session auto-configuration to use customizers
This commit reworks Spring Session auto-configuration to avoid extending Spring Session's configuration classes. Instead, those configuration classes are now imported and customizations are applied using dedicated (Reactive)SessionRepositoryCustomizer beans. See gh-32554
This commit is contained in:
parent
a9c1b4a7c3
commit
ad8753923a
|
@ -16,18 +16,19 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.session;
|
package org.springframework.boot.autoconfigure.session;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import com.hazelcast.core.HazelcastInstance;
|
import com.hazelcast.core.HazelcastInstance;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.session.SessionRepository;
|
import org.springframework.session.SessionRepository;
|
||||||
|
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||||
import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository;
|
import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository;
|
||||||
import org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration;
|
import org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration;
|
||||||
|
|
||||||
|
@ -47,19 +48,22 @@ import org.springframework.session.hazelcast.config.annotation.web.http.Hazelcas
|
||||||
class HazelcastSessionConfiguration {
|
class HazelcastSessionConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
public static class SpringBootHazelcastHttpSessionConfiguration extends HazelcastHttpSessionConfiguration {
|
@Import(HazelcastHttpSessionConfiguration.class)
|
||||||
|
static class SpringBootHazelcastHttpSessionConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Bean
|
||||||
public void customize(SessionProperties sessionProperties,
|
SessionRepositoryCustomizer<HazelcastIndexedSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
HazelcastSessionProperties hazelcastSessionProperties, ServerProperties serverProperties) {
|
SessionProperties sessionProperties, HazelcastSessionProperties hazelcastSessionProperties,
|
||||||
Duration timeout = sessionProperties
|
ServerProperties serverProperties) {
|
||||||
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout());
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
if (timeout != null) {
|
return (sessionRepository) -> {
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
map.from(sessionProperties
|
||||||
}
|
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()))
|
||||||
setSessionMapName(hazelcastSessionProperties.getMapName());
|
.to((timeout) -> sessionRepository.setDefaultMaxInactiveInterval((int) timeout.getSeconds()));
|
||||||
setFlushMode(hazelcastSessionProperties.getFlushMode());
|
map.from(hazelcastSessionProperties::getMapName).to(sessionRepository::setSessionMapName);
|
||||||
setSaveMode(hazelcastSessionProperties.getSaveMode());
|
map.from(hazelcastSessionProperties::getFlushMode).to(sessionRepository::setFlushMode);
|
||||||
|
map.from(hazelcastSessionProperties::getSaveMode).to(sessionRepository::setSaveMode);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,16 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.session;
|
package org.springframework.boot.autoconfigure.session;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
|
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
|
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
|
@ -35,6 +33,7 @@ import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.session.SessionRepository;
|
import org.springframework.session.SessionRepository;
|
||||||
|
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||||
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
|
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
|
||||||
import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
|
import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
|
||||||
import org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration;
|
import org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessionConfiguration;
|
||||||
|
@ -65,20 +64,23 @@ class JdbcSessionConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class SpringBootJdbcHttpSessionConfiguration extends JdbcHttpSessionConfiguration {
|
@Import(JdbcHttpSessionConfiguration.class)
|
||||||
|
static class SpringBootJdbcHttpSessionConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Bean
|
||||||
void customize(SessionProperties sessionProperties, JdbcSessionProperties jdbcSessionProperties,
|
SessionRepositoryCustomizer<JdbcIndexedSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
|
SessionProperties sessionProperties, JdbcSessionProperties jdbcSessionProperties,
|
||||||
ServerProperties serverProperties) {
|
ServerProperties serverProperties) {
|
||||||
Duration timeout = sessionProperties
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout());
|
return (sessionRepository) -> {
|
||||||
if (timeout != null) {
|
map.from(sessionProperties
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()))
|
||||||
}
|
.to((timeout) -> sessionRepository.setDefaultMaxInactiveInterval((int) timeout.getSeconds()));
|
||||||
setTableName(jdbcSessionProperties.getTableName());
|
map.from(jdbcSessionProperties::getTableName).to(sessionRepository::setTableName);
|
||||||
setCleanupCron(jdbcSessionProperties.getCleanupCron());
|
map.from(jdbcSessionProperties::getFlushMode).to(sessionRepository::setFlushMode);
|
||||||
setFlushMode(jdbcSessionProperties.getFlushMode());
|
map.from(jdbcSessionProperties::getSaveMode).to(sessionRepository::setSaveMode);
|
||||||
setSaveMode(jdbcSessionProperties.getSaveMode());
|
map.from(jdbcSessionProperties::getCleanupCron).to(sessionRepository::setCleanupCron);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,18 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.session;
|
package org.springframework.boot.autoconfigure.session;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
|
||||||
import org.springframework.session.ReactiveSessionRepository;
|
import org.springframework.session.ReactiveSessionRepository;
|
||||||
|
import org.springframework.session.config.ReactiveSessionRepositoryCustomizer;
|
||||||
import org.springframework.session.data.mongo.ReactiveMongoSessionRepository;
|
import org.springframework.session.data.mongo.ReactiveMongoSessionRepository;
|
||||||
import org.springframework.session.data.mongo.config.annotation.web.reactive.ReactiveMongoWebSessionConfiguration;
|
import org.springframework.session.data.mongo.config.annotation.web.reactive.ReactiveMongoWebSessionConfiguration;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ import org.springframework.session.data.mongo.config.annotation.web.reactive.Rea
|
||||||
*
|
*
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Weix Sun
|
* @author Weix Sun
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass({ ReactiveMongoOperations.class, ReactiveMongoSessionRepository.class })
|
@ConditionalOnClass({ ReactiveMongoOperations.class, ReactiveMongoSessionRepository.class })
|
||||||
|
@ -44,17 +46,20 @@ import org.springframework.session.data.mongo.config.annotation.web.reactive.Rea
|
||||||
class MongoReactiveSessionConfiguration {
|
class MongoReactiveSessionConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class SpringBootReactiveMongoWebSessionConfiguration extends ReactiveMongoWebSessionConfiguration {
|
@Import(ReactiveMongoWebSessionConfiguration.class)
|
||||||
|
static class SpringBootMongoWebSessionConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Bean
|
||||||
void customize(SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties,
|
ReactiveSessionRepositoryCustomizer<ReactiveMongoSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
|
SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties,
|
||||||
ServerProperties serverProperties) {
|
ServerProperties serverProperties) {
|
||||||
Duration timeout = sessionProperties
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
.determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout());
|
return (sessionRepository) -> {
|
||||||
if (timeout != null) {
|
map.from(sessionProperties
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
.determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout()))
|
||||||
}
|
.to((timeout) -> sessionRepository.setMaxInactiveIntervalInSeconds((int) timeout.getSeconds()));
|
||||||
setCollectionName(mongoSessionProperties.getCollectionName());
|
map.from(mongoSessionProperties::getCollectionName).to(sessionRepository::setCollectionName);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,18 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.session;
|
package org.springframework.boot.autoconfigure.session;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.mongodb.core.MongoOperations;
|
import org.springframework.data.mongodb.core.MongoOperations;
|
||||||
import org.springframework.session.SessionRepository;
|
import org.springframework.session.SessionRepository;
|
||||||
|
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||||
import org.springframework.session.data.mongo.MongoIndexedSessionRepository;
|
import org.springframework.session.data.mongo.MongoIndexedSessionRepository;
|
||||||
import org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration;
|
import org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ import org.springframework.session.data.mongo.config.annotation.web.http.MongoHt
|
||||||
*
|
*
|
||||||
* @author Eddú Meléndez
|
* @author Eddú Meléndez
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass({ MongoOperations.class, MongoIndexedSessionRepository.class })
|
@ConditionalOnClass({ MongoOperations.class, MongoIndexedSessionRepository.class })
|
||||||
|
@ -44,17 +46,20 @@ import org.springframework.session.data.mongo.config.annotation.web.http.MongoHt
|
||||||
class MongoSessionConfiguration {
|
class MongoSessionConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
public static class SpringBootMongoHttpSessionConfiguration extends MongoHttpSessionConfiguration {
|
@Import(MongoHttpSessionConfiguration.class)
|
||||||
|
static class SpringBootMongoHttpSessionConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Bean
|
||||||
public void customize(SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties,
|
SessionRepositoryCustomizer<MongoIndexedSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
|
SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties,
|
||||||
ServerProperties serverProperties) {
|
ServerProperties serverProperties) {
|
||||||
Duration timeout = sessionProperties
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout());
|
return (sessionRepository) -> {
|
||||||
if (timeout != null) {
|
map.from(sessionProperties
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()))
|
||||||
}
|
.to((timeout) -> sessionRepository.setMaxInactiveIntervalInSeconds((int) timeout.getSeconds()));
|
||||||
setCollectionName(mongoSessionProperties.getCollectionName());
|
map.from(mongoSessionProperties::getCollectionName).to(sessionRepository::setCollectionName);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,17 +16,18 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.session;
|
package org.springframework.boot.autoconfigure.session;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
|
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
|
||||||
import org.springframework.session.ReactiveSessionRepository;
|
import org.springframework.session.ReactiveSessionRepository;
|
||||||
|
import org.springframework.session.config.ReactiveSessionRepositoryCustomizer;
|
||||||
import org.springframework.session.data.redis.ReactiveRedisSessionRepository;
|
import org.springframework.session.data.redis.ReactiveRedisSessionRepository;
|
||||||
import org.springframework.session.data.redis.config.annotation.web.server.RedisWebSessionConfiguration;
|
import org.springframework.session.data.redis.config.annotation.web.server.RedisWebSessionConfiguration;
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ import org.springframework.session.data.redis.config.annotation.web.server.Redis
|
||||||
*
|
*
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Weix Sun
|
* @author Weix Sun
|
||||||
|
* @author Vedran Pavic
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnClass({ ReactiveRedisConnectionFactory.class, ReactiveRedisSessionRepository.class })
|
@ConditionalOnClass({ ReactiveRedisConnectionFactory.class, ReactiveRedisSessionRepository.class })
|
||||||
|
@ -44,18 +46,21 @@ import org.springframework.session.data.redis.config.annotation.web.server.Redis
|
||||||
class RedisReactiveSessionConfiguration {
|
class RedisReactiveSessionConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class SpringBootRedisWebSessionConfiguration extends RedisWebSessionConfiguration {
|
@Import(RedisWebSessionConfiguration.class)
|
||||||
|
static class SpringBootRedisWebSessionConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Bean
|
||||||
void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
|
ReactiveSessionRepositoryCustomizer<ReactiveRedisSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
|
SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
|
||||||
ServerProperties serverProperties) {
|
ServerProperties serverProperties) {
|
||||||
Duration timeout = sessionProperties
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
.determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout());
|
return (sessionRepository) -> {
|
||||||
if (timeout != null) {
|
map.from(sessionProperties
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
.determineTimeout(() -> serverProperties.getReactive().getSession().getTimeout()))
|
||||||
}
|
.to((timeout) -> sessionRepository.setDefaultMaxInactiveInterval((int) timeout.getSeconds()));
|
||||||
setRedisNamespace(redisSessionProperties.getNamespace());
|
map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace);
|
||||||
setSaveMode(redisSessionProperties.getSaveMode());
|
map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,22 +16,23 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.session;
|
package org.springframework.boot.autoconfigure.session;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.boot.context.properties.PropertyMapper;
|
||||||
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.session.SessionRepository;
|
import org.springframework.session.SessionRepository;
|
||||||
|
import org.springframework.session.config.SessionRepositoryCustomizer;
|
||||||
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
|
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
|
||||||
|
import org.springframework.session.data.redis.RedisSessionRepository;
|
||||||
import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction;
|
import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction;
|
||||||
import org.springframework.session.data.redis.config.ConfigureRedisAction;
|
import org.springframework.session.data.redis.config.ConfigureRedisAction;
|
||||||
import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;
|
import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;
|
||||||
|
@ -59,10 +60,12 @@ class RedisSessionConfiguration {
|
||||||
static class DefaultRedisSessionConfiguration {
|
static class DefaultRedisSessionConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class SpringBootRedisHttpSessionConfiguration extends RedisHttpSessionConfiguration {
|
@Import(RedisHttpSessionConfiguration.class)
|
||||||
|
static class SpringBootRedisHttpSessionConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Bean
|
||||||
void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
|
SessionRepositoryCustomizer<RedisSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
|
SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
|
||||||
ServerProperties serverProperties) {
|
ServerProperties serverProperties) {
|
||||||
String cleanupCron = redisSessionProperties.getCleanupCron();
|
String cleanupCron = redisSessionProperties.getCleanupCron();
|
||||||
if (cleanupCron != null) {
|
if (cleanupCron != null) {
|
||||||
|
@ -71,14 +74,15 @@ class RedisSessionConfiguration {
|
||||||
"Cron-based cleanup is only supported when spring.session.redis.repository-type is set to "
|
"Cron-based cleanup is only supported when spring.session.redis.repository-type is set to "
|
||||||
+ "indexed.");
|
+ "indexed.");
|
||||||
}
|
}
|
||||||
Duration timeout = sessionProperties
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout());
|
return (sessionRepository) -> {
|
||||||
if (timeout != null) {
|
map.from(sessionProperties
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()))
|
||||||
}
|
.to(sessionRepository::setDefaultMaxInactiveInterval);
|
||||||
setRedisNamespace(redisSessionProperties.getNamespace());
|
map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace);
|
||||||
setFlushMode(redisSessionProperties.getFlushMode());
|
map.from(redisSessionProperties::getFlushMode).to(sessionRepository::setFlushMode);
|
||||||
setSaveMode(redisSessionProperties.getSaveMode());
|
map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -99,23 +103,24 @@ class RedisSessionConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
static class SpringBootRedisIndexedHttpSessionConfiguration extends RedisIndexedHttpSessionConfiguration {
|
@Import(RedisIndexedHttpSessionConfiguration.class)
|
||||||
|
static class SpringBootRedisIndexedHttpSessionConfiguration {
|
||||||
|
|
||||||
private static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
|
@Bean
|
||||||
|
SessionRepositoryCustomizer<RedisIndexedSessionRepository> springBootSessionRepositoryCustomizer(
|
||||||
@Autowired
|
SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
|
||||||
void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
|
|
||||||
ServerProperties serverProperties) {
|
ServerProperties serverProperties) {
|
||||||
Duration timeout = sessionProperties
|
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
|
||||||
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout());
|
return (sessionRepository) -> {
|
||||||
if (timeout != null) {
|
map.from(sessionProperties
|
||||||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
.determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()))
|
||||||
}
|
.to((timeout) -> sessionRepository
|
||||||
setRedisNamespace(redisSessionProperties.getNamespace());
|
.setDefaultMaxInactiveInterval((int) timeout.getSeconds()));
|
||||||
setFlushMode(redisSessionProperties.getFlushMode());
|
map.from(redisSessionProperties::getNamespace).to(sessionRepository::setRedisKeyNamespace);
|
||||||
setSaveMode(redisSessionProperties.getSaveMode());
|
map.from(redisSessionProperties::getFlushMode).to(sessionRepository::setFlushMode);
|
||||||
String cleanupCron = redisSessionProperties.getCleanupCron();
|
map.from(redisSessionProperties::getSaveMode).to(sessionRepository::setSaveMode);
|
||||||
setCleanupCron((cleanupCron != null) ? cleanupCron : DEFAULT_CLEANUP_CRON);
|
map.from(redisSessionProperties::getCleanupCron).to(sessionRepository::setCleanupCron);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration.SpringBootJdbcHttpSessionConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
import org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializer;
|
||||||
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
import org.springframework.boot.sql.init.DatabaseInitializationMode;
|
||||||
|
@ -86,12 +85,10 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
|
||||||
assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval",
|
assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval",
|
||||||
(int) new ServerProperties().getServlet().getSession().getTimeout().getSeconds());
|
(int) new ServerProperties().getServlet().getSession().getTimeout().getSeconds());
|
||||||
assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION");
|
assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION");
|
||||||
|
assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", "0 * * * * *");
|
||||||
assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema())
|
assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema())
|
||||||
.isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
.isEqualTo(DatabaseInitializationMode.EMBEDDED);
|
||||||
assertThat(context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")).isEmpty();
|
assertThat(context.getBean(JdbcOperations.class).queryForList("select * from SPRING_SESSION")).isEmpty();
|
||||||
SpringBootJdbcHttpSessionConfiguration configuration = context
|
|
||||||
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
|
|
||||||
assertThat(configuration).hasFieldOrPropertyWithValue("cleanupCron", "0 * * * * *");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -142,29 +139,27 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
|
||||||
void customCleanupCron() {
|
void customCleanupCron() {
|
||||||
this.contextRunner.withPropertyValues("spring.session.jdbc.cleanup-cron=0 0 12 * * *").run((context) -> {
|
this.contextRunner.withPropertyValues("spring.session.jdbc.cleanup-cron=0 0 12 * * *").run((context) -> {
|
||||||
assertThat(context.getBean(JdbcSessionProperties.class).getCleanupCron()).isEqualTo("0 0 12 * * *");
|
assertThat(context.getBean(JdbcSessionProperties.class).getCleanupCron()).isEqualTo("0 0 12 * * *");
|
||||||
SpringBootJdbcHttpSessionConfiguration configuration = context
|
JdbcIndexedSessionRepository repository = validateSessionRepository(context,
|
||||||
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
|
JdbcIndexedSessionRepository.class);
|
||||||
assertThat(configuration).hasFieldOrPropertyWithValue("cleanupCron", "0 0 12 * * *");
|
assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", "0 0 12 * * *");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void customFlushMode() {
|
void customFlushMode() {
|
||||||
this.contextRunner.withPropertyValues("spring.session.jdbc.flush-mode=immediate").run((context) -> {
|
this.contextRunner.withPropertyValues("spring.session.jdbc.flush-mode=immediate").run((context) -> {
|
||||||
assertThat(context.getBean(JdbcSessionProperties.class).getFlushMode()).isEqualTo(FlushMode.IMMEDIATE);
|
JdbcIndexedSessionRepository repository = validateSessionRepository(context,
|
||||||
SpringBootJdbcHttpSessionConfiguration configuration = context
|
JdbcIndexedSessionRepository.class);
|
||||||
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
|
assertThat(repository).hasFieldOrPropertyWithValue("flushMode", FlushMode.IMMEDIATE);
|
||||||
assertThat(configuration).hasFieldOrPropertyWithValue("flushMode", FlushMode.IMMEDIATE);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void customSaveMode() {
|
void customSaveMode() {
|
||||||
this.contextRunner.withPropertyValues("spring.session.jdbc.save-mode=on-get-attribute").run((context) -> {
|
this.contextRunner.withPropertyValues("spring.session.jdbc.save-mode=on-get-attribute").run((context) -> {
|
||||||
assertThat(context.getBean(JdbcSessionProperties.class).getSaveMode()).isEqualTo(SaveMode.ON_GET_ATTRIBUTE);
|
JdbcIndexedSessionRepository repository = validateSessionRepository(context,
|
||||||
SpringBootJdbcHttpSessionConfiguration configuration = context
|
JdbcIndexedSessionRepository.class);
|
||||||
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
|
assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE);
|
||||||
assertThat(configuration).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.session.RedisSessionConfiguration.IndexedRedisSessionConfiguration.SpringBootRedisIndexedHttpSessionConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||||
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
import org.springframework.boot.context.properties.source.InvalidConfigurationPropertyValueException;
|
||||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||||
|
@ -191,9 +190,7 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
|
||||||
assertThat(repository).hasFieldOrPropertyWithValue("namespace", keyNamespace);
|
assertThat(repository).hasFieldOrPropertyWithValue("namespace", keyNamespace);
|
||||||
assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode);
|
assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode);
|
||||||
assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode);
|
assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode);
|
||||||
SpringBootRedisIndexedHttpSessionConfiguration configuration = context
|
assertThat(repository).hasFieldOrPropertyWithValue("cleanupCron", cleanupCron);
|
||||||
.getBean(SpringBootRedisIndexedHttpSessionConfiguration.class);
|
|
||||||
assertThat(configuration).hasFieldOrPropertyWithValue("cleanupCron", cleanupCron);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue