diff --git a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java index 4d3ed9cce..f17927d27 100644 --- a/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java +++ b/spring-session-jdbc/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java @@ -48,7 +48,6 @@ import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.support.lob.DefaultLobHandler; import org.springframework.jdbc.support.lob.LobHandler; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.session.FindByIndexNameSessionRepository; import org.springframework.session.MapSession; import org.springframework.session.Session; @@ -535,7 +534,6 @@ public Map findByIndexNameAndIndexValue(String indexName, return sessionMap; } - @Scheduled(cron = "${spring.session.cleanup.cron.expression:0 * * * * *}") public void cleanUpExpiredSessions() { Integer deletedCount = this.transactionOperations.execute(transactionStatus -> JdbcOperationsSessionRepository.this.jdbcOperations.update( 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 ac6271ddd..0de8dcb88 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 @@ -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. @@ -58,8 +58,8 @@ * More advanced configurations can extend {@link JdbcHttpSessionConfiguration} instead. * * For additional information on how to configure data access related concerns, please - * refer to the - * + * refer to the * Spring Framework Reference Documentation. * * @author Vedran Pavic @@ -80,11 +80,16 @@ 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. - * + * 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 + */ + 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 d24727e8b..4685e4a89 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 @@ -28,7 +28,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportAware; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.GenericConversionService; @@ -37,6 +36,9 @@ import org.springframework.core.type.AnnotationMetadata; import org.springframework.jdbc.support.lob.LobHandler; 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.jdbc.JdbcOperationsSessionRepository; import org.springframework.transaction.PlatformTransactionManager; @@ -59,38 +61,37 @@ @Configuration @EnableScheduling public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration - implements BeanClassLoaderAware, ImportAware, EmbeddedValueResolverAware { + implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware, + SchedulingConfigurer { - private String tableName; + static final String DEFAULT_CLEANUP_CRON = "0 * * * * *"; - private Integer maxInactiveIntervalInSeconds; + private String tableName = JdbcOperationsSessionRepository.DEFAULT_TABLE_NAME; - private LobHandler lobHandler; + private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - @Autowired(required = false) - @Qualifier("conversionService") - private ConversionService conversionService; + private String cleanupCron = DEFAULT_CLEANUP_CRON; + + private DataSource dataSource; + + private PlatformTransactionManager transactionManager; + + private LobHandler lobHandler; private ConversionService springSessionConversionService; + private ConversionService conversionService; + private ClassLoader classLoader; private StringValueResolver embeddedValueResolver; @Bean - public JdbcOperationsSessionRepository sessionRepository( - @SpringSessionDataSource ObjectProvider springSessionDataSource, - ObjectProvider dataSource, - PlatformTransactionManager transactionManager) { - DataSource dataSourceToUse = springSessionDataSource.getIfAvailable(); - if (dataSourceToUse == null) { - dataSourceToUse = dataSource.getObject(); - } + public JdbcOperationsSessionRepository sessionRepository() { JdbcOperationsSessionRepository sessionRepository = new JdbcOperationsSessionRepository( - dataSourceToUse, transactionManager); - String tableName = getTableName(); - if (StringUtils.hasText(tableName)) { - sessionRepository.setTableName(tableName); + this.dataSource, this.transactionManager); + if (StringUtils.hasText(this.tableName)) { + sessionRepository.setTableName(this.tableName); } sessionRepository .setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds); @@ -104,35 +105,38 @@ else if (this.conversionService != null) { sessionRepository.setConversionService(this.conversionService); } else { - GenericConversionService conversionService = createConversionServiceWithBeanClassLoader(); - sessionRepository.setConversionService(conversionService); + sessionRepository + .setConversionService(createConversionServiceWithBeanClassLoader()); } return sessionRepository; } - /** - * This must be a separate method because some ClassLoaders load the entire method - * definition even if an if statement guards against it loading. This means that older - * versions of Spring would cause a NoSuchMethodError if this were defined in - * {@link #sessionRepository(ObjectProvider, ObjectProvider, PlatformTransactionManager)}. - * - * @return the default {@link ConversionService} - */ - private GenericConversionService createConversionServiceWithBeanClassLoader() { - GenericConversionService conversionService = new GenericConversionService(); - conversionService.addConverter(Object.class, byte[].class, - new SerializingConverter()); - conversionService.addConverter(byte[].class, Object.class, - new DeserializingConverter(this.classLoader)); - return conversionService; + public void setTableName(String tableName) { + this.tableName = tableName; } - /* (non-Javadoc) - * @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang.ClassLoader) - */ - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.classLoader = classLoader; + public void setMaxInactiveIntervalInSeconds(Integer maxInactiveIntervalInSeconds) { + this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; + } + + public void setCleanupCron(String cleanupCron) { + this.cleanupCron = cleanupCron; + } + + @Autowired + public void setDataSource( + @SpringSessionDataSource ObjectProvider springSessionDataSource, + ObjectProvider dataSource) { + DataSource dataSourceToUse = springSessionDataSource.getIfAvailable(); + if (dataSourceToUse == null) { + dataSourceToUse = dataSource.getObject(); + } + this.dataSource = dataSourceToUse; + } + + @Autowired + public void setTransactionManager(PlatformTransactionManager transactionManager) { + this.transactionManager = transactionManager; } @Autowired(required = false) @@ -147,48 +151,53 @@ public void setSpringSessionConversionService(ConversionService conversionServic this.springSessionConversionService = conversionService; } - public void setTableName(String tableName) { - this.tableName = tableName; + @Autowired(required = false) + @Qualifier("conversionService") + public void setConversionService(ConversionService conversionService) { + this.conversionService = conversionService; } - public void setMaxInactiveIntervalInSeconds(Integer maxInactiveIntervalInSeconds) { - this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; } - private String getTableName() { - String systemProperty = System.getProperty("spring.session.jdbc.tableName", ""); - if (StringUtils.hasText(systemProperty)) { - return systemProperty; - } - return this.tableName; + @Override + public void setEmbeddedValueResolver(StringValueResolver resolver) { + this.embeddedValueResolver = resolver; } @Override public void setImportMetadata(AnnotationMetadata importMetadata) { - Map enableAttrMap = importMetadata + Map attributeMap = importMetadata .getAnnotationAttributes(EnableJdbcHttpSession.class.getName()); - AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); - String tableNameValue = enableAttrs.getString("tableName"); + AnnotationAttributes attributes = AnnotationAttributes.fromMap(attributeMap); + String tableNameValue = attributes.getString("tableName"); if (StringUtils.hasText(tableNameValue)) { this.tableName = this.embeddedValueResolver .resolveStringValue(tableNameValue); } - this.maxInactiveIntervalInSeconds = enableAttrs + this.maxInactiveIntervalInSeconds = attributes .getNumber("maxInactiveIntervalInSeconds"); + String cleanupCron = attributes.getString("cleanupCron"); + if (StringUtils.hasText(cleanupCron)) { + this.cleanupCron = this.embeddedValueResolver.resolveStringValue(cleanupCron); + } } @Override - public void setEmbeddedValueResolver(StringValueResolver resolver) { - this.embeddedValueResolver = resolver; + public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { + taskRegistrar.addCronTask(() -> sessionRepository().cleanUpExpiredSessions(), + this.cleanupCron); } - /** - * Property placeholder to process the @Scheduled annotation. - * @return the {@link PropertySourcesPlaceholderConfigurer} to use - */ - @Bean - public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); + private GenericConversionService createConversionServiceWithBeanClassLoader() { + GenericConversionService conversionService = new GenericConversionService(); + conversionService.addConverter(Object.class, byte[].class, + new SerializingConverter()); + conversionService.addConverter(byte[].class, Object.class, + new DeserializingConverter(this.classLoader)); + return conversionService; } } diff --git a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationCustomCronTests.java b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationCustomCronTests.java deleted file mode 100644 index cc263f8eb..000000000 --- a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationCustomCronTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.jdbc.config.annotation.web.http; - -import javax.sql.DataSource; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.transaction.PlatformTransactionManager; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - -/** - * @author Rob Winch - * - */ -public class JdbcHttpSessionConfigurationCustomCronTests { - - AnnotationConfigApplicationContext context; - - @Before - public void setup() { - this.context = new AnnotationConfigApplicationContext(); - } - - @After - public void closeContext() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void overrideCron() { - this.context.register(Config.class); - - assertThatThrownBy(() -> - JdbcHttpSessionConfigurationCustomCronTests.this.context.refresh()) - .hasStackTraceContaining( - "Encountered invalid @Scheduled method 'cleanUpExpiredSessions': Cron expression must consist of 6 fields (found 1 in \"oops\")"); - } - - @EnableJdbcHttpSession - @Configuration - @PropertySource("classpath:spring-session-cleanup-cron-expression-oops.properties") - static class Config { - @Bean - public DataSource dataSource() { - return mock(DataSource.class); - } - - @Bean - public PlatformTransactionManager transactionManager() { - return mock(PlatformTransactionManager.class); - } - } -} diff --git a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java index 0e9e3d0a4..c0ddec426 100644 --- a/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java +++ b/spring-session-jdbc/src/test/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfigurationTests.java @@ -53,7 +53,7 @@ public class JdbcHttpSessionConfigurationTests { private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600; - private static final String TABLE_NAME_SYSTEM_PROPERTY = "spring.session.jdbc.tableName"; + private static final String CLEANUP_CRON_EXPRESSION = "0 0 * * * *"; @Rule public final ExpectedException thrown = ExpectedException.none(); @@ -70,22 +70,24 @@ public void closeContext() { @Test public void noDataSourceConfiguration() { this.thrown.expect(BeanCreationException.class); - this.thrown.expectMessage("sessionRepository"); + this.thrown.expectMessage( + "expected at least 1 bean which qualifies as autowire candidate"); registerAndRefresh(NoDataSourceConfiguration.class); } @Test public void defaultConfiguration() { - registerAndRefresh(DefaultConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, DefaultConfiguration.class); assertThat(this.context.getBean(JdbcOperationsSessionRepository.class)) .isNotNull(); } @Test - public void customTableName() { - registerAndRefresh(CustomTableNameConfiguration.class); + public void customTableNameAnnotation() { + registerAndRefresh(DataSourceConfiguration.class, + CustomTableNameAnnotationConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); @@ -95,50 +97,33 @@ public void customTableName() { } @Test - public void customTableNameSystemProperty() { - System.setProperty(TABLE_NAME_SYSTEM_PROPERTY, TABLE_NAME); + public void customTableNameSetter() { + registerAndRefresh(DataSourceConfiguration.class, + CustomTableNameSetterConfiguration.class); - try { - registerAndRefresh(DefaultConfiguration.class); - - JdbcOperationsSessionRepository repository = this.context - .getBean(JdbcOperationsSessionRepository.class); - assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "tableName")) - .isEqualTo(TABLE_NAME); - } - finally { - System.clearProperty(TABLE_NAME_SYSTEM_PROPERTY); - } - } - - @Test - public void setCustomTableName() { - registerAndRefresh(BaseConfiguration.class, - CustomTableNameSetConfiguration.class); - - JdbcHttpSessionConfiguration repository = this.context - .getBean(JdbcHttpSessionConfiguration.class); + JdbcOperationsSessionRepository repository = this.context + .getBean(JdbcOperationsSessionRepository.class); assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "tableName")).isEqualTo( - "custom_session"); + assertThat(ReflectionTestUtils.getField(repository, "tableName")) + .isEqualTo(TABLE_NAME); } @Test - public void setCustomMaxInactiveIntervalInSeconds() { - registerAndRefresh(BaseConfiguration.class, - CustomMaxInactiveIntervalInSecondsSetConfiguration.class); + public void customMaxInactiveIntervalInSecondsAnnotation() { + registerAndRefresh(DataSourceConfiguration.class, + CustomMaxInactiveIntervalInSecondsAnnotationConfiguration.class); - JdbcHttpSessionConfiguration repository = this.context - .getBean(JdbcHttpSessionConfiguration.class); + JdbcOperationsSessionRepository repository = this.context + .getBean(JdbcOperationsSessionRepository.class); assertThat(repository).isNotNull(); - assertThat(ReflectionTestUtils.getField(repository, "maxInactiveIntervalInSeconds")).isEqualTo( - 10); + assertThat(ReflectionTestUtils.getField(repository, "defaultMaxInactiveInterval")) + .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); } @Test - public void customMaxInactiveIntervalInSeconds() { - registerAndRefresh(CustomMaxInactiveIntervalInSecondsConfiguration.class); + public void customMaxInactiveIntervalInSecondsSetter() { + registerAndRefresh(DataSourceConfiguration.class, + CustomMaxInactiveIntervalInSecondsSetterConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); @@ -147,13 +132,39 @@ public void customMaxInactiveIntervalInSeconds() { .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); } + @Test + public void customCleanupCronAnnotation() { + registerAndRefresh(DataSourceConfiguration.class, + CustomCleanupCronExpressionAnnotationConfiguration.class); + + JdbcHttpSessionConfiguration configuration = this.context + .getBean(JdbcHttpSessionConfiguration.class); + assertThat(configuration).isNotNull(); + assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron")) + .isEqualTo(CLEANUP_CRON_EXPRESSION); + } + + @Test + public void customCleanupCronSetter() { + registerAndRefresh(DataSourceConfiguration.class, + CustomCleanupCronExpressionSetterConfiguration.class); + + JdbcHttpSessionConfiguration configuration = this.context + .getBean(JdbcHttpSessionConfiguration.class); + assertThat(configuration).isNotNull(); + assertThat(ReflectionTestUtils.getField(configuration, "cleanupCron")) + .isEqualTo(CLEANUP_CRON_EXPRESSION); + } + @Test public void qualifiedDataSourceConfiguration() { - registerAndRefresh(QualifiedDataSourceConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + QualifiedDataSourceConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); - DataSource dataSource = this.context.getBean("qualifiedDataSource", DataSource.class); + DataSource dataSource = this.context.getBean("qualifiedDataSource", + DataSource.class); assertThat(repository).isNotNull(); assertThat(dataSource).isNotNull(); JdbcOperations jdbcOperations = (JdbcOperations) ReflectionTestUtils @@ -165,11 +176,13 @@ public void qualifiedDataSourceConfiguration() { @Test public void primaryDataSourceConfiguration() { - registerAndRefresh(PrimaryDataSourceConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + PrimaryDataSourceConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); - DataSource dataSource = this.context.getBean("primaryDataSource", DataSource.class); + DataSource dataSource = this.context.getBean("primaryDataSource", + DataSource.class); assertThat(repository).isNotNull(); assertThat(dataSource).isNotNull(); JdbcOperations jdbcOperations = (JdbcOperations) ReflectionTestUtils @@ -181,11 +194,13 @@ public void primaryDataSourceConfiguration() { @Test public void qualifiedAndPrimaryDataSourceConfiguration() { - registerAndRefresh(QualifiedAndPrimaryDataSourceConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + QualifiedAndPrimaryDataSourceConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); - DataSource dataSource = this.context.getBean("qualifiedDataSource", DataSource.class); + DataSource dataSource = this.context.getBean("qualifiedDataSource", + DataSource.class); assertThat(repository).isNotNull(); assertThat(dataSource).isNotNull(); JdbcOperations jdbcOperations = (JdbcOperations) ReflectionTestUtils @@ -197,7 +212,8 @@ public void qualifiedAndPrimaryDataSourceConfiguration() { @Test public void namedDataSourceConfiguration() { - registerAndRefresh(NamedDataSourceConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + NamedDataSourceConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); @@ -214,14 +230,16 @@ public void namedDataSourceConfiguration() { @Test public void multipleDataSourceConfiguration() { this.thrown.expect(BeanCreationException.class); - this.thrown.expectMessage("sessionRepository"); + this.thrown.expectMessage("expected single matching bean but found 2"); - registerAndRefresh(MultipleDataSourceConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + MultipleDataSourceConfiguration.class); } @Test public void customLobHandlerConfiguration() { - registerAndRefresh(CustomLobHandlerConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + CustomLobHandlerConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); @@ -234,7 +252,8 @@ public void customLobHandlerConfiguration() { @Test public void customConversionServiceConfiguration() { - registerAndRefresh(CustomConversionServiceConfiguration.class); + registerAndRefresh(DataSourceConfiguration.class, + CustomConversionServiceConfiguration.class); JdbcOperationsSessionRepository repository = this.context .getBean(JdbcOperationsSessionRepository.class); @@ -249,10 +268,14 @@ public void customConversionServiceConfiguration() { @Test public void resolveTableNameByPropertyPlaceholder() { - this.context.setEnvironment(new MockEnvironment().withProperty("session.jdbc.tableName", "custom_session_table")); - registerAndRefresh(CustomJdbcHttpSessionConfiguration.class); - JdbcHttpSessionConfiguration configuration = this.context.getBean(JdbcHttpSessionConfiguration.class); - assertThat(ReflectionTestUtils.getField(configuration, "tableName")).isEqualTo("custom_session_table"); + this.context.setEnvironment(new MockEnvironment() + .withProperty("session.jdbc.tableName", "custom_session_table")); + registerAndRefresh(DataSourceConfiguration.class, + CustomJdbcHttpSessionConfiguration.class); + JdbcHttpSessionConfiguration configuration = this.context + .getBean(JdbcHttpSessionConfiguration.class); + assertThat(ReflectionTestUtils.getField(configuration, "tableName")) + .isEqualTo("custom_session_table"); } private void registerAndRefresh(Class... annotatedClasses) { @@ -260,12 +283,13 @@ private void registerAndRefresh(Class... annotatedClasses) { this.context.refresh(); } - @Configuration @EnableJdbcHttpSession static class NoDataSourceConfiguration { + } - static class BaseConfiguration { + @Configuration + static class DataSourceConfiguration { @Bean public DataSource defaultDataSource() { @@ -279,43 +303,57 @@ public PlatformTransactionManager transactionManager() { } - @Configuration @EnableJdbcHttpSession - static class DefaultConfiguration extends BaseConfiguration { + static class DefaultConfiguration { + } - @Configuration @EnableJdbcHttpSession(tableName = TABLE_NAME) - static class CustomTableNameConfiguration extends BaseConfiguration { + static class CustomTableNameAnnotationConfiguration { + } @Configuration - static class CustomTableNameSetConfiguration extends JdbcHttpSessionConfiguration { + static class CustomTableNameSetterConfiguration extends JdbcHttpSessionConfiguration { - CustomTableNameSetConfiguration() { - setTableName("custom_session"); + CustomTableNameSetterConfiguration() { + setTableName(TABLE_NAME); } } + @EnableJdbcHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) + static class CustomMaxInactiveIntervalInSecondsAnnotationConfiguration { + + } + @Configuration - static class CustomMaxInactiveIntervalInSecondsSetConfiguration extends JdbcHttpSessionConfiguration { + static class CustomMaxInactiveIntervalInSecondsSetterConfiguration + extends JdbcHttpSessionConfiguration { - CustomMaxInactiveIntervalInSecondsSetConfiguration() { - setMaxInactiveIntervalInSeconds(10); + CustomMaxInactiveIntervalInSecondsSetterConfiguration() { + setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS); } } - @Configuration - @EnableJdbcHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class CustomMaxInactiveIntervalInSecondsConfiguration - extends BaseConfiguration { + @EnableJdbcHttpSession(cleanupCron = CLEANUP_CRON_EXPRESSION) + static class CustomCleanupCronExpressionAnnotationConfiguration { + } @Configuration + static class CustomCleanupCronExpressionSetterConfiguration + extends JdbcHttpSessionConfiguration { + + CustomCleanupCronExpressionSetterConfiguration() { + setCleanupCron(CLEANUP_CRON_EXPRESSION); + } + + } + @EnableJdbcHttpSession - static class QualifiedDataSourceConfiguration extends BaseConfiguration { + static class QualifiedDataSourceConfiguration { @Bean @SpringSessionDataSource @@ -325,9 +363,8 @@ public DataSource qualifiedDataSource() { } - @Configuration @EnableJdbcHttpSession - static class PrimaryDataSourceConfiguration extends BaseConfiguration { + static class PrimaryDataSourceConfiguration { @Bean @Primary @@ -337,9 +374,8 @@ public DataSource primaryDataSource() { } - @Configuration @EnableJdbcHttpSession - static class QualifiedAndPrimaryDataSourceConfiguration extends BaseConfiguration { + static class QualifiedAndPrimaryDataSourceConfiguration { @Bean @SpringSessionDataSource @@ -355,9 +391,8 @@ public DataSource primaryDataSource() { } - @Configuration @EnableJdbcHttpSession - static class NamedDataSourceConfiguration extends BaseConfiguration { + static class NamedDataSourceConfiguration { @Bean public DataSource dataSource() { @@ -366,9 +401,8 @@ public DataSource dataSource() { } - @Configuration @EnableJdbcHttpSession - static class MultipleDataSourceConfiguration extends BaseConfiguration { + static class MultipleDataSourceConfiguration { @Bean public DataSource secondaryDataSource() { @@ -377,9 +411,8 @@ public DataSource secondaryDataSource() { } - @Configuration @EnableJdbcHttpSession - static class CustomLobHandlerConfiguration extends BaseConfiguration { + static class CustomLobHandlerConfiguration { @Bean public LobHandler springSessionLobHandler() { @@ -388,9 +421,8 @@ public LobHandler springSessionLobHandler() { } - @Configuration @EnableJdbcHttpSession - static class CustomConversionServiceConfiguration extends BaseConfiguration { + static class CustomConversionServiceConfiguration { @Bean public ConversionService springSessionConversionService() { @@ -399,9 +431,8 @@ public ConversionService springSessionConversionService() { } - @Configuration @EnableJdbcHttpSession(tableName = "${session.jdbc.tableName}") - static class CustomJdbcHttpSessionConfiguration extends BaseConfiguration { + static class CustomJdbcHttpSessionConfiguration { @Bean public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { diff --git a/spring-session-jdbc/src/test/resources/spring-session-cleanup-cron-expression-oops.properties b/spring-session-jdbc/src/test/resources/spring-session-cleanup-cron-expression-oops.properties deleted file mode 100644 index 17db1ef20..000000000 --- a/spring-session-jdbc/src/test/resources/spring-session-cleanup-cron-expression-oops.properties +++ /dev/null @@ -1 +0,0 @@ -spring.session.cleanup.cron.expression=oops \ No newline at end of file