Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
a2763563
Commit
a2763563
authored
Oct 30, 2017
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add auto-configuration for Spring Session's reactive support
Closes gh-9850
parent
bdab4aa9
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
648 additions
and
76 deletions
+648
-76
AbstractSessionCondition.java
.../boot/autoconfigure/session/AbstractSessionCondition.java
+12
-4
HazelcastSessionConfiguration.java
.../autoconfigure/session/HazelcastSessionConfiguration.java
+1
-1
JdbcSessionConfiguration.java
.../boot/autoconfigure/session/JdbcSessionConfiguration.java
+1
-1
MongoReactiveSessionConfiguration.java
...oconfigure/session/MongoReactiveSessionConfiguration.java
+59
-0
MongoSessionConfiguration.java
...boot/autoconfigure/session/MongoSessionConfiguration.java
+1
-1
NoOpReactiveSessionConfiguration.java
...toconfigure/session/NoOpReactiveSessionConfiguration.java
+35
-0
NoOpSessionConfiguration.java
.../boot/autoconfigure/session/NoOpSessionConfiguration.java
+1
-1
ReactiveSessionCondition.java
.../boot/autoconfigure/session/ReactiveSessionCondition.java
+32
-0
RedisReactiveSessionConfiguration.java
...oconfigure/session/RedisReactiveSessionConfiguration.java
+65
-0
RedisSessionConfiguration.java
...boot/autoconfigure/session/RedisSessionConfiguration.java
+1
-1
ServletSessionCondition.java
...k/boot/autoconfigure/session/ServletSessionCondition.java
+35
-0
SessionAutoConfiguration.java
.../boot/autoconfigure/session/SessionAutoConfiguration.java
+143
-38
SessionStoreMappings.java
...work/boot/autoconfigure/session/SessionStoreMappings.java
+45
-14
HttpHandlerAutoConfiguration.java
...oconfigure/web/reactive/HttpHandlerAutoConfiguration.java
+3
-13
AbstractSessionAutoConfigurationTests.java
...figure/session/AbstractSessionAutoConfigurationTests.java
+16
-0
ReactiveSessionAutoConfigurationMongoTests.java
...e/session/ReactiveSessionAutoConfigurationMongoTests.java
+95
-0
ReactiveSessionAutoConfigurationRedisTests.java
...e/session/ReactiveSessionAutoConfigurationRedisTests.java
+95
-0
pom.xml
spring-boot-project/spring-boot-dependencies/pom.xml
+1
-1
spring-boot-features.adoc
...ing-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+7
-1
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionCondition.java
→
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/
Abstract
SessionCondition.java
View file @
a2763563
...
...
@@ -16,6 +16,7 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
session
;
import
org.springframework.boot.WebApplicationType
;
import
org.springframework.boot.autoconfigure.condition.ConditionMessage
;
import
org.springframework.boot.autoconfigure.condition.ConditionOutcome
;
import
org.springframework.boot.autoconfigure.condition.SpringBootCondition
;
...
...
@@ -27,13 +28,20 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
import
org.springframework.core.type.AnnotationMetadata
;
/**
*
General condition used with all session configuration classe
s.
*
Base class for Servlet and reactive session condition
s.
*
* @author Tommy Ludwig
* @author Stephane Nicoll
* @author Madhura Bhave
* @author Andy Wilkinson
*/
class
SessionCondition
extends
SpringBootCondition
{
class
AbstractSessionCondition
extends
SpringBootCondition
{
private
final
WebApplicationType
webApplicationType
;
protected
AbstractSessionCondition
(
WebApplicationType
webApplicationType
)
{
this
.
webApplicationType
=
webApplicationType
;
}
@Override
public
ConditionOutcome
getMatchOutcome
(
ConditionContext
context
,
...
...
@@ -41,8 +49,8 @@ class SessionCondition extends SpringBootCondition {
ConditionMessage
.
Builder
message
=
ConditionMessage
.
forCondition
(
"Session Condition"
);
Environment
environment
=
context
.
getEnvironment
();
StoreType
required
=
SessionStoreMappings
.
getType
(
((
AnnotationMetadata
)
metadata
).
getClassName
());
StoreType
required
=
SessionStoreMappings
.
getType
(
this
.
webApplicationType
,
((
AnnotationMetadata
)
metadata
).
getClassName
());
if
(!
environment
.
containsProperty
(
"spring.session.store-type"
))
{
return
ConditionOutcome
.
match
(
message
.
didNotFind
(
"property"
,
"properties"
)
.
items
(
ConditionMessage
.
Style
.
QUOTE
,
"spring.session.store-type"
));
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java
View file @
a2763563
...
...
@@ -41,7 +41,7 @@ import org.springframework.session.hazelcast.config.annotation.web.http.Hazelcas
@ConditionalOnClass
(
HazelcastSessionRepository
.
class
)
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@ConditionalOnBean
(
HazelcastInstance
.
class
)
@Conditional
(
SessionCondition
.
class
)
@Conditional
(
Se
rvletSe
ssionCondition
.
class
)
@EnableConfigurationProperties
(
HazelcastSessionProperties
.
class
)
class
HazelcastSessionConfiguration
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java
View file @
a2763563
...
...
@@ -43,7 +43,7 @@ import org.springframework.session.jdbc.config.annotation.web.http.JdbcHttpSessi
@ConditionalOnClass
({
JdbcTemplate
.
class
,
JdbcOperationsSessionRepository
.
class
})
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@ConditionalOnBean
(
DataSource
.
class
)
@Conditional
(
SessionCondition
.
class
)
@Conditional
(
Se
rvletSe
ssionCondition
.
class
)
@EnableConfigurationProperties
(
JdbcSessionProperties
.
class
)
class
JdbcSessionConfiguration
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoReactiveSessionConfiguration.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.mongodb.core.ReactiveMongoOperations
;
import
org.springframework.session.ReactiveSessionRepository
;
import
org.springframework.session.data.mongo.config.annotation.web.reactive.ReactiveMongoWebSessionConfiguration
;
/**
* Mongo-backed reactive session configuration.
*
* @author Andy Wilkinson
*/
@Configuration
@ConditionalOnClass
(
ReactiveMongoWebSessionConfiguration
.
class
)
@ConditionalOnMissingBean
(
ReactiveSessionRepository
.
class
)
@ConditionalOnBean
(
ReactiveMongoOperations
.
class
)
@Conditional
(
ReactiveSessionCondition
.
class
)
@EnableConfigurationProperties
(
MongoSessionProperties
.
class
)
class
MongoReactiveSessionConfiguration
{
@Configuration
static
class
SpringBootReactiveMongoWebSessionConfiguration
extends
ReactiveMongoWebSessionConfiguration
{
@Autowired
public
void
customize
(
SessionProperties
sessionProperties
,
MongoSessionProperties
mongoSessionProperties
)
{
Integer
timeout
=
sessionProperties
.
getTimeout
();
if
(
timeout
!=
null
)
{
setMaxInactiveIntervalInSeconds
(
timeout
);
}
setCollectionName
(
mongoSessionProperties
.
getCollectionName
());
}
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java
View file @
a2763563
...
...
@@ -37,7 +37,7 @@ import org.springframework.session.data.mongo.config.annotation.web.http.MongoHt
@ConditionalOnClass
(
MongoHttpSessionConfiguration
.
class
)
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@ConditionalOnBean
(
MongoOperations
.
class
)
@Conditional
(
SessionCondition
.
class
)
@Conditional
(
Se
rvletSe
ssionCondition
.
class
)
@EnableConfigurationProperties
(
MongoSessionProperties
.
class
)
class
MongoSessionConfiguration
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/NoOpReactiveSessionConfiguration.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.session.ReactiveSessionRepository
;
/**
* No-op session configuration used to disable Spring Session using the environment.
*
* @author Tommy Ludwig
* @author Andy Wilkinson
*/
@Configuration
@ConditionalOnMissingBean
(
ReactiveSessionRepository
.
class
)
@Conditional
(
ReactiveSessionCondition
.
class
)
class
NoOpReactiveSessionConfiguration
{
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/NoOpSessionConfiguration.java
View file @
a2763563
...
...
@@ -28,7 +28,7 @@ import org.springframework.session.SessionRepository;
*/
@Configuration
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@Conditional
(
SessionCondition
.
class
)
@Conditional
(
Se
rvletSe
ssionCondition
.
class
)
class
NoOpSessionConfiguration
{
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/ReactiveSessionCondition.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.springframework.boot.WebApplicationType
;
/**
* General condition used with all reactive session configuration classes.
*
* @author Andy Wilkinson
*/
class
ReactiveSessionCondition
extends
AbstractSessionCondition
{
ReactiveSessionCondition
()
{
super
(
WebApplicationType
.
REACTIVE
);
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisReactiveSessionConfiguration.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.ReactiveRedisConnectionFactory
;
import
org.springframework.session.ReactiveSessionRepository
;
import
org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository
;
import
org.springframework.session.data.redis.config.annotation.web.server.RedisWebSessionConfiguration
;
/**
* Redis-backed reactive session configuration.
*
* @author Andy Wilkinson
*/
@Configuration
@ConditionalOnClass
({
ReactiveRedisConnectionFactory
.
class
,
ReactiveRedisOperationsSessionRepository
.
class
})
@ConditionalOnMissingBean
(
ReactiveSessionRepository
.
class
)
@ConditionalOnBean
(
ReactiveRedisConnectionFactory
.
class
)
@Conditional
(
ReactiveSessionCondition
.
class
)
@EnableConfigurationProperties
(
RedisSessionProperties
.
class
)
class
RedisReactiveSessionConfiguration
{
@Configuration
static
class
SpringBootRedisWebSessionConfiguration
extends
RedisWebSessionConfiguration
{
private
SessionProperties
sessionProperties
;
@Autowired
public
void
customize
(
SessionProperties
sessionProperties
,
RedisSessionProperties
redisSessionProperties
)
{
this
.
sessionProperties
=
sessionProperties
;
Integer
timeout
=
this
.
sessionProperties
.
getTimeout
();
if
(
timeout
!=
null
)
{
setMaxInactiveIntervalInSeconds
(
timeout
);
}
setRedisNamespace
(
redisSessionProperties
.
getNamespace
());
setRedisFlushMode
(
redisSessionProperties
.
getFlushMode
());
}
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java
View file @
a2763563
...
...
@@ -42,7 +42,7 @@ import org.springframework.session.data.redis.config.annotation.web.http.RedisHt
@ConditionalOnClass
({
RedisTemplate
.
class
,
RedisOperationsSessionRepository
.
class
})
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@ConditionalOnBean
(
RedisConnectionFactory
.
class
)
@Conditional
(
SessionCondition
.
class
)
@Conditional
(
Se
rvletSe
ssionCondition
.
class
)
@EnableConfigurationProperties
(
RedisSessionProperties
.
class
)
class
RedisSessionConfiguration
{
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/ServletSessionCondition.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.springframework.boot.WebApplicationType
;
/**
* General condition used with all servlet session configuration classes.
*
* @author Tommy Ludwig
* @author Stephane Nicoll
* @author Madhura Bhave
* @author Andy Wilkinson
*/
class
ServletSessionCondition
extends
AbstractSessionCondition
{
ServletSessionCondition
()
{
super
(
WebApplicationType
.
SERVLET
);
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.java
View file @
a2763563
...
...
@@ -17,11 +17,13 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
session
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
javax.annotation.PostConstruct
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.boot.WebApplicationType
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.AutoConfigureBefore
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
...
...
@@ -43,6 +45,7 @@ import org.springframework.context.annotation.Configuration;
import
org.springframework.context.annotation.Import
;
import
org.springframework.context.annotation.ImportSelector
;
import
org.springframework.core.type.AnnotationMetadata
;
import
org.springframework.session.ReactiveSessionRepository
;
import
org.springframework.session.Session
;
import
org.springframework.session.SessionRepository
;
...
...
@@ -69,77 +72,116 @@ public class SessionAutoConfiguration {
@Configuration
@ConditionalOnWebApplication
(
type
=
Type
.
SERVLET
)
@Import
({
Se
ssionRepositoryConfiguration
.
class
,
SessionRepositoryValidator
.
class
,
@Import
({
Se
rvlet
SessionRepositoryValidator
.
class
,
SessionRepositoryFilterConfiguration
.
class
})
static
class
ServletSessionConfiguration
{
@Configuration
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@Import
({
ServletSessionRepositoryImplementationValidator
.
class
,
ServletSessionConfigurationImportSelector
.
class
})
static
class
ServletSessionRepositoryConfiguration
{
}
}
@Configuration
@ConditionalOnWebApplication
(
type
=
Type
.
REACTIVE
)
@Import
(
ReactiveSessionRepositoryValidator
.
class
)
static
class
ReactiveSessionConfiguration
{
}
@Configuration
@ConditionalOnMissingBean
(
ReactiveSessionRepository
.
class
)
@Import
({
ReactiveSessionRepositoryImplementationValidator
.
class
,
ReactiveSessionConfigurationImportSelector
.
class
})
static
class
ReactiveSessionRepositoryConfiguration
{
@Configuration
@ConditionalOnMissingBean
(
SessionRepository
.
class
)
@Import
({
SessionRepositoryImplementationValidator
.
class
,
SessionConfigurationImportSelector
.
class
})
static
class
SessionRepositoryConfiguration
{
}
}
/**
* {@link ImportSelector} to add {@link StoreType} configuration classes.
* {@link ImportSelector}
base class
to add {@link StoreType} configuration classes.
*/
static
class
SessionConfigurationImportSelector
implements
ImportSelector
{
static
abstract
class
SessionConfigurationImportSelector
implements
ImportSelector
{
@Override
public
String
[]
selectImports
(
AnnotationMetadata
importingClassMetadata
)
{
protected
final
String
[]
selectImports
(
AnnotationMetadata
importingClassMetadata
,
WebApplicationType
webApplicationType
)
{
List
<
String
>
imports
=
new
ArrayList
<>();
StoreType
[]
types
=
StoreType
.
values
();
String
[]
imports
=
new
String
[
types
.
length
];
for
(
int
i
=
0
;
i
<
types
.
length
;
i
++)
{
imports
[
i
]
=
SessionStoreMappings
.
getConfigurationClass
(
types
[
i
]);
imports
.
add
(
SessionStoreMappings
.
getConfigurationClass
(
webApplicationType
,
types
[
i
]));
}
return
imports
;
return
imports
.
toArray
(
new
String
[
imports
.
size
()])
;
}
}
/**
* Bean used to validate that only one supported implementation is available in the
* classpath when the store-type property is not set.
* {@link ImportSelector} to add {@link StoreType} configuration classes for reactive
* web applications.
*/
static
class
ReactiveSessionConfigurationImportSelector
extends
SessionConfigurationImportSelector
{
@Override
public
String
[]
selectImports
(
AnnotationMetadata
importingClassMetadata
)
{
return
super
.
selectImports
(
importingClassMetadata
,
WebApplicationType
.
REACTIVE
);
}
}
/**
* {@link ImportSelector} to add {@link StoreType} configuration classes for Servlet
* web applications.
*/
static
class
SessionRepositoryImplementationValidator
{
static
class
ServletSessionConfigurationImportSelector
extends
SessionConfigurationImportSelector
{
@Override
public
String
[]
selectImports
(
AnnotationMetadata
importingClassMetadata
)
{
return
super
.
selectImports
(
importingClassMetadata
,
WebApplicationType
.
SERVLET
);
}
}
/**
* Base class for beans used to validate that only one supported implementation is
* available in the classpath when the store-type property is not set.
*/
static
class
AbstractSessionRepositoryImplementationValidator
{
private
final
List
<
String
>
candidates
;
private
final
ClassLoader
classLoader
;
private
final
SessionProperties
sessionProperties
;
SessionRepositoryImplementationValidator
(
ApplicationContext
applicationContext
,
SessionProperties
sessionProperties
)
{
AbstractSessionRepositoryImplementationValidator
(
ApplicationContext
applicationContext
,
SessionProperties
sessionProperties
,
List
<
String
>
candidates
)
{
this
.
classLoader
=
applicationContext
.
getClassLoader
();
this
.
sessionProperties
=
sessionProperties
;
this
.
candidates
=
candidates
;
}
@PostConstruct
public
void
checkAvailableImplementations
()
{
List
<
Class
<?>>
candidates
=
new
ArrayList
<>();
addCandidate
(
candidates
,
"org.springframework.session.hazelcast.HazelcastSessionRepository"
);
addCandidate
(
candidates
,
"org.springframework.session.jdbc.JdbcOperationsSessionRepository"
);
addCandidate
(
candidates
,
"org.springframework.session.data.mongo.MongoOperationsSessionRepository"
);
addCandidate
(
candidates
,
"org.springframework.session.data.redis.RedisOperationsSessionRepository"
);
List
<
Class
<?>>
availableCandidates
=
new
ArrayList
<>();
for
(
String
candidate
:
this
.
candidates
)
{
addCandidateIfAvailable
(
availableCandidates
,
candidate
);
}
StoreType
storeType
=
this
.
sessionProperties
.
getStoreType
();
if
(
c
andidates
.
size
()
>
1
&&
storeType
==
null
)
{
throw
new
NonUniqueSessionRepositoryException
(
c
andidates
);
if
(
availableC
andidates
.
size
()
>
1
&&
storeType
==
null
)
{
throw
new
NonUniqueSessionRepositoryException
(
availableC
andidates
);
}
}
private
void
addCandidate
(
List
<
Class
<?>>
candidates
,
String
type
)
{
private
void
addCandidate
IfAvailable
(
List
<
Class
<?>>
candidates
,
String
type
)
{
try
{
Class
<?>
candidate
=
this
.
classLoader
.
loadClass
(
type
);
if
(
candidate
!=
null
)
{
...
...
@@ -153,17 +195,52 @@ public class SessionAutoConfiguration {
}
/**
* Bean used to validate that a {@link SessionRepository} exists and provide a
* meaningful message if that's not the case.
* Bean used to validate that only one supported implementation is available in the
* classpath when the store-type property is not set.
*/
static
class
ServletSessionRepositoryImplementationValidator
extends
AbstractSessionRepositoryImplementationValidator
{
ServletSessionRepositoryImplementationValidator
(
ApplicationContext
applicationContext
,
SessionProperties
sessionProperties
)
{
super
(
applicationContext
,
sessionProperties
,
Arrays
.
asList
(
"org.springframework.session.hazelcast.HazelcastSessionRepository"
,
"org.springframework.session.jdbc.JdbcOperationsSessionRepository"
,
"org.springframework.session.data.mongo.MongoOperationsSessionRepository"
,
"org.springframework.session.data.redis.RedisOperationsSessionRepository"
));
}
}
/**
* Bean used to validate that only one supported implementation is available in the
* classpath when the store-type property is not set.
*/
static
class
SessionRepositoryValidator
{
static
class
ReactiveSessionRepositoryImplementationValidator
extends
AbstractSessionRepositoryImplementationValidator
{
private
SessionProperties
sessionProperties
;
ReactiveSessionRepositoryImplementationValidator
(
ApplicationContext
applicationContext
,
SessionProperties
sessionProperties
)
{
super
(
applicationContext
,
sessionProperties
,
Arrays
.
asList
(
"org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository"
,
"org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository"
));
}
private
ObjectProvider
<
SessionRepository
<?>>
sessionRepositoryProvider
;
}
SessionRepositoryValidator
(
SessionProperties
sessionProperties
,
ObjectProvider
<
SessionRepository
<?>>
sessionRepositoryProvider
)
{
/**
* Base class for validating that a (reactive) session repository bean exists.
*/
static
class
AbstractSessionRepositoryValidator
{
private
final
SessionProperties
sessionProperties
;
private
final
ObjectProvider
<?>
sessionRepositoryProvider
;
protected
AbstractSessionRepositoryValidator
(
SessionProperties
sessionProperties
,
ObjectProvider
<?>
sessionRepositoryProvider
)
{
this
.
sessionProperties
=
sessionProperties
;
this
.
sessionRepositoryProvider
=
sessionRepositoryProvider
;
}
...
...
@@ -184,4 +261,32 @@ public class SessionAutoConfiguration {
}
/**
* Bean used to validate that a {@link SessionRepository} exists and provide a
* meaningful message if that's not the case.
*/
static
class
ServletSessionRepositoryValidator
extends
AbstractSessionRepositoryValidator
{
ServletSessionRepositoryValidator
(
SessionProperties
sessionProperties
,
ObjectProvider
<
SessionRepository
<?>>
sessionRepositoryProvider
)
{
super
(
sessionProperties
,
sessionRepositoryProvider
);
}
}
/**
* Bean used to validate that a {@link SessionRepository} exists and provide a
* meaningful message if that's not the case.
*/
static
class
ReactiveSessionRepositoryValidator
extends
AbstractSessionRepositoryValidator
{
ReactiveSessionRepositoryValidator
(
SessionProperties
sessionProperties
,
ObjectProvider
<
ReactiveSessionRepository
<?>>
sessionRepositoryProvider
)
{
super
(
sessionProperties
,
sessionRepositoryProvider
);
}
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionStoreMappings.java
View file @
a2763563
...
...
@@ -20,6 +20,7 @@ import java.util.Collections;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.springframework.boot.WebApplicationType
;
import
org.springframework.util.Assert
;
/**
...
...
@@ -30,32 +31,62 @@ import org.springframework.util.Assert;
*/
final
class
SessionStoreMappings
{
private
static
final
Map
<
StoreType
,
Class
<?
>>
MAPPINGS
;
private
static
final
Map
<
StoreType
,
Map
<
WebApplicationType
,
Class
<?>
>>
MAPPINGS
;
static
{
Map
<
StoreType
,
Class
<?>>
mappings
=
new
HashMap
<>();
mappings
.
put
(
StoreType
.
REDIS
,
RedisSessionConfiguration
.
class
);
mappings
.
put
(
StoreType
.
MONGODB
,
MongoSessionConfiguration
.
class
);
mappings
.
put
(
StoreType
.
JDBC
,
JdbcSessionConfiguration
.
class
);
mappings
.
put
(
StoreType
.
HAZELCAST
,
HazelcastSessionConfiguration
.
class
);
mappings
.
put
(
StoreType
.
NONE
,
NoOpSessionConfiguration
.
class
);
Map
<
StoreType
,
Map
<
WebApplicationType
,
Class
<?>>>
mappings
=
new
HashMap
<>();
mappings
.
put
(
StoreType
.
REDIS
,
createMapping
(
RedisSessionConfiguration
.
class
,
RedisReactiveSessionConfiguration
.
class
));
mappings
.
put
(
StoreType
.
MONGODB
,
createMapping
(
MongoSessionConfiguration
.
class
,
MongoReactiveSessionConfiguration
.
class
));
mappings
.
put
(
StoreType
.
JDBC
,
createMapping
(
JdbcSessionConfiguration
.
class
));
mappings
.
put
(
StoreType
.
HAZELCAST
,
createMapping
(
HazelcastSessionConfiguration
.
class
));
mappings
.
put
(
StoreType
.
NONE
,
createMapping
(
NoOpSessionConfiguration
.
class
,
NoOpReactiveSessionConfiguration
.
class
));
MAPPINGS
=
Collections
.
unmodifiableMap
(
mappings
);
}
static
Map
<
WebApplicationType
,
Class
<?>>
createMapping
(
Class
<?>
servletConfiguration
)
{
return
createMapping
(
servletConfiguration
,
null
);
}
static
Map
<
WebApplicationType
,
Class
<?>>
createMapping
(
Class
<?>
servletConfiguration
,
Class
<?>
reactiveConfiguration
)
{
Map
<
WebApplicationType
,
Class
<?>>
mapping
=
new
HashMap
<>();
mapping
.
put
(
WebApplicationType
.
SERVLET
,
servletConfiguration
);
if
(
reactiveConfiguration
!=
null
)
{
mapping
.
put
(
WebApplicationType
.
REACTIVE
,
reactiveConfiguration
);
}
return
mapping
;
}
private
SessionStoreMappings
()
{
}
static
String
getConfigurationClass
(
StoreType
sessionStoreType
)
{
Class
<?>
configurationClass
=
MAPPINGS
.
get
(
sessionStoreType
);
Assert
.
state
(
configurationClass
!=
null
,
static
String
getConfigurationClass
(
WebApplicationType
webApplicationType
,
StoreType
sessionStoreType
)
{
Map
<
WebApplicationType
,
Class
<?>>
configurationClasses
=
MAPPINGS
.
get
(
sessionStoreType
);
Assert
.
state
(
configurationClasses
!=
null
,
()
->
"Unknown session store type "
+
sessionStoreType
);
Class
<?>
configurationClass
=
configurationClasses
.
get
(
webApplicationType
);
if
(
configurationClass
==
null
)
{
return
null
;
}
return
configurationClass
.
getName
();
}
static
StoreType
getType
(
String
configurationClassName
)
{
for
(
Map
.
Entry
<
StoreType
,
Class
<?>>
entry
:
MAPPINGS
.
entrySet
())
{
if
(
entry
.
getValue
().
getName
().
equals
(
configurationClassName
))
{
return
entry
.
getKey
();
static
StoreType
getType
(
WebApplicationType
webApplicationType
,
String
configurationClassName
)
{
for
(
Map
.
Entry
<
StoreType
,
Map
<
WebApplicationType
,
Class
<?>>>
storeEntry
:
MAPPINGS
.
entrySet
())
{
for
(
Map
.
Entry
<
WebApplicationType
,
Class
<?>>
entry
:
storeEntry
.
getValue
()
.
entrySet
())
{
if
(
entry
.
getValue
().
getName
().
equals
(
configurationClassName
))
{
return
storeEntry
.
getKey
();
}
}
}
throw
new
IllegalStateException
(
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/HttpHandlerAutoConfiguration.java
View file @
a2763563
...
...
@@ -16,7 +16,6 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
reactive
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.AutoConfigureOrder
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
...
...
@@ -30,14 +29,12 @@ import org.springframework.core.Ordered;
import
org.springframework.http.server.reactive.HttpHandler
;
import
org.springframework.web.reactive.DispatcherHandler
;
import
org.springframework.web.server.adapter.WebHttpHandlerBuilder
;
import
org.springframework.web.server.session.WebSessionManager
;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link HttpHandler}.
*
* @author Brian Clozel
* @author Stephane Nicoll
* @author Andy Wilkinson
* @since 2.0.0
*/
@Configuration
...
...
@@ -58,16 +55,9 @@ public class HttpHandlerAutoConfiguration {
}
@Bean
public
HttpHandler
httpHandler
(
ObjectProvider
<
WebSessionManager
>
webSessionManagerProvider
)
{
WebHttpHandlerBuilder
builder
=
WebHttpHandlerBuilder
.
applicationContext
(
this
.
applicationContext
);
WebSessionManager
webSessionManager
=
webSessionManagerProvider
.
getIfAvailable
();
if
(
webSessionManager
!=
null
)
{
builder
.
sessionManager
(
webSessionManager
);
}
return
builder
.
build
();
public
HttpHandler
httpHandler
()
{
return
WebHttpHandlerBuilder
.
applicationContext
(
this
.
applicationContext
)
.
build
();
}
}
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/AbstractSessionAutoConfigurationTests.java
View file @
a2763563
...
...
@@ -17,7 +17,9 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
session
;
import
org.springframework.beans.DirectFieldAccessor
;
import
org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext
;
import
org.springframework.boot.test.context.assertj.AssertableWebApplicationContext
;
import
org.springframework.session.ReactiveSessionRepository
;
import
org.springframework.session.SessionRepository
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
...
@@ -42,4 +44,18 @@ public abstract class AbstractSessionAutoConfigurationTests {
.
getPropertyValue
(
"defaultMaxInactiveInterval"
);
}
protected
<
T
extends
ReactiveSessionRepository
<?>>
T
validateSessionRepository
(
AssertableReactiveWebApplicationContext
context
,
Class
<
T
>
type
)
{
assertThat
(
context
).
hasSingleBean
(
ReactiveSessionRepository
.
class
);
ReactiveSessionRepository
<?>
repository
=
context
.
getBean
(
ReactiveSessionRepository
.
class
);
assertThat
(
repository
).
as
(
"Wrong session repository type"
).
isInstanceOf
(
type
);
return
type
.
cast
(
repository
);
}
protected
Integer
getSessionTimeout
(
ReactiveSessionRepository
<?>
sessionRepository
)
{
return
(
Integer
)
new
DirectFieldAccessor
(
sessionRepository
)
.
getPropertyValue
(
"defaultMaxInactiveInterval"
);
}
}
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.junit.Test
;
import
org.springframework.beans.DirectFieldAccessor
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
;
import
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration
;
import
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration
;
import
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration
;
import
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration
;
import
org.springframework.boot.test.context.HideClassesClassLoader
;
import
org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext
;
import
org.springframework.boot.test.context.runner.ContextConsumer
;
import
org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner
;
import
org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository
;
import
org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Mongo-specific tests for {@link SessionAutoConfiguration}.
*
* @author Andy Wilkinson
*/
public
class
ReactiveSessionAutoConfigurationMongoTests
extends
AbstractSessionAutoConfigurationTests
{
private
final
ReactiveWebApplicationContextRunner
contextRunner
=
new
ReactiveWebApplicationContextRunner
()
.
withConfiguration
(
AutoConfigurations
.
of
(
SessionAutoConfiguration
.
class
));
@Test
public
void
defaultConfig
()
{
this
.
contextRunner
.
withPropertyValues
(
"spring.session.store-type=mongodb"
)
.
withConfiguration
(
AutoConfigurations
.
of
(
EmbeddedMongoAutoConfiguration
.
class
,
MongoAutoConfiguration
.
class
,
MongoDataAutoConfiguration
.
class
,
MongoReactiveAutoConfiguration
.
class
,
MongoReactiveDataAutoConfiguration
.
class
))
.
run
(
validateSpringSessionUsesMongo
(
"sessions"
));
}
@Test
public
void
defaultConfigWithUniqueStoreImplementation
()
{
this
.
contextRunner
.
withClassLoader
(
new
HideClassesClassLoader
(
ReactiveRedisOperationsSessionRepository
.
class
))
.
withConfiguration
(
AutoConfigurations
.
of
(
EmbeddedMongoAutoConfiguration
.
class
,
MongoAutoConfiguration
.
class
,
MongoDataAutoConfiguration
.
class
,
MongoReactiveAutoConfiguration
.
class
,
MongoReactiveDataAutoConfiguration
.
class
))
.
run
(
validateSpringSessionUsesMongo
(
"sessions"
));
}
@Test
public
void
mongoSessionStoreWithCustomizations
()
{
this
.
contextRunner
.
withConfiguration
(
AutoConfigurations
.
of
(
EmbeddedMongoAutoConfiguration
.
class
,
MongoAutoConfiguration
.
class
,
MongoDataAutoConfiguration
.
class
,
MongoReactiveAutoConfiguration
.
class
,
MongoReactiveDataAutoConfiguration
.
class
))
.
withPropertyValues
(
"spring.session.store-type=mongodb"
,
"spring.session.mongodb.collection-name=foo"
)
.
run
(
validateSpringSessionUsesMongo
(
"foo"
));
}
private
ContextConsumer
<
AssertableReactiveWebApplicationContext
>
validateSpringSessionUsesMongo
(
String
collectionName
)
{
return
(
context
)
->
{
ReactiveMongoOperationsSessionRepository
repository
=
validateSessionRepository
(
context
,
ReactiveMongoOperationsSessionRepository
.
class
);
assertThat
(
new
DirectFieldAccessor
(
repository
)
.
getPropertyValue
(
"collectionName"
)).
isEqualTo
(
collectionName
);
};
}
}
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java
0 → 100644
View file @
a2763563
/*
* Copyright 2012-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
.
boot
.
autoconfigure
.
session
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.springframework.beans.DirectFieldAccessor
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReport
;
import
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
;
import
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration
;
import
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportMessage
;
import
org.springframework.boot.test.context.HideClassesClassLoader
;
import
org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext
;
import
org.springframework.boot.test.context.runner.ContextConsumer
;
import
org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner
;
import
org.springframework.boot.testsupport.rule.RedisTestServer
;
import
org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository
;
import
org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository
;
import
org.springframework.session.data.redis.RedisFlushMode
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Reactive Redis-specific tests for {@link SessionAutoConfiguration}.
*
* @author Stephane Nicoll
* @author Andy Wilkinson
*/
public
class
ReactiveSessionAutoConfigurationRedisTests
extends
AbstractSessionAutoConfigurationTests
{
@Rule
public
final
RedisTestServer
redis
=
new
RedisTestServer
();
protected
final
ReactiveWebApplicationContextRunner
contextRunner
=
new
ReactiveWebApplicationContextRunner
()
.
withConfiguration
(
AutoConfigurations
.
of
(
SessionAutoConfiguration
.
class
));
@Test
public
void
defaultConfig
()
{
this
.
contextRunner
.
withPropertyValues
(
"spring.session.store-type=redis"
)
.
withConfiguration
(
AutoConfigurations
.
of
(
RedisAutoConfiguration
.
class
,
RedisReactiveAutoConfiguration
.
class
))
.
run
(
validateSpringSessionUsesRedis
(
RedisFlushMode
.
ON_SAVE
));
}
@Test
public
void
defaultConfigWithUniqueStoreImplementation
()
{
this
.
contextRunner
.
withClassLoader
(
new
HideClassesClassLoader
(
ReactiveMongoOperationsSessionRepository
.
class
))
.
withConfiguration
(
AutoConfigurations
.
of
(
RedisAutoConfiguration
.
class
,
RedisReactiveAutoConfiguration
.
class
))
.
run
(
validateSpringSessionUsesRedis
(
RedisFlushMode
.
ON_SAVE
));
}
@Test
public
void
redisSessionStoreWithCustomizations
()
{
this
.
contextRunner
.
withConfiguration
(
AutoConfigurations
.
of
(
RedisAutoConfiguration
.
class
,
RedisReactiveAutoConfiguration
.
class
))
.
withPropertyValues
(
"spring.session.store-type=redis"
,
"spring.session.redis.namespace=foo"
,
"spring.session.redis.flush-mode=immediate"
)
.
run
(
validateSpringSessionUsesRedis
(
RedisFlushMode
.
IMMEDIATE
));
}
private
ContextConsumer
<
AssertableReactiveWebApplicationContext
>
validateSpringSessionUsesRedis
(
RedisFlushMode
flushMode
)
{
return
(
context
)
->
{
System
.
out
.
println
(
new
ConditionEvaluationReportMessage
(
context
.
getBean
(
ConditionEvaluationReport
.
class
)));
ReactiveRedisOperationsSessionRepository
repository
=
validateSessionRepository
(
context
,
ReactiveRedisOperationsSessionRepository
.
class
);
assertThat
(
new
DirectFieldAccessor
(
repository
)
.
getPropertyValue
(
"redisFlushMode"
)).
isEqualTo
(
flushMode
);
};
}
}
spring-boot-project/spring-boot-dependencies/pom.xml
View file @
a2763563
...
...
@@ -157,7 +157,7 @@
<spring-retry.version>
1.2.1.RELEASE
</spring-retry.version>
<spring-security.version>
5.0.0.BUILD-SNAPSHOT
</spring-security.version>
<spring-session.version>
2.0.0.BUILD-SNAPSHOT
</spring-session.version>
<spring-session-data-mongodb.version>
2.0.0.
M4
</spring-session-data-mongodb.version>
<spring-session-data-mongodb.version>
2.0.0.
BUILD-SNAPSHOT
</spring-session-data-mongodb.version>
<spring-social.version>
2.0.0.M4
</spring-social.version>
<spring-social-facebook.version>
3.0.0.M3
</spring-social-facebook.version>
<spring-social-linkedin.version>
2.0.0.M3
</spring-social-linkedin.version>
...
...
spring-boot-project/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
View file @
a2763563
...
...
@@ -5506,13 +5506,19 @@ classes for more details.
[[boot-features-session]]
== Spring Session
Spring Boot provides Spring Session auto-configuration for a wide range of stores:
Spring Boot provides Spring Session auto-configuration for a wide range of stores. When
building a Servlet web application, the following stores can be auto-configured:
* JDBC
* Redis
* Hazelcast
* MongoDB
When building a reactive web applicaiton, the following stores can be auto-configured:
* Redis
* MongoDB
If Spring Session is available, you must choose the
{sc-spring-boot-autoconfigure}/session/StoreType.{sc-ext}[`StoreType`] that you wish to
use to store the sessions. For instance to use JDBC as backend store, you'd configure
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment