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
81fef71f
Commit
81fef71f
authored
Apr 20, 2017
by
Phillip Webb
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '1.5.x'
parents
359854eb
bddc1908
Changes
30
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
1382 additions
and
553 deletions
+1382
-553
EndpointMvcIntegrationTests.java
...ot/actuate/autoconfigure/EndpointMvcIntegrationTests.java
+8
-6
DefaultValidatorConfiguration.java
...toconfigure/validation/DefaultValidatorConfiguration.java
+47
-0
DelegatingValidator.java
...rk/boot/autoconfigure/validation/DelegatingValidator.java
+82
-0
Jsr303ValidatorAdapterConfiguration.java
...igure/validation/Jsr303ValidatorAdapterConfiguration.java
+46
-0
SpringValidator.java
...mework/boot/autoconfigure/validation/SpringValidator.java
+0
-145
ValidationAutoConfiguration.java
...autoconfigure/validation/ValidationAutoConfiguration.java
+5
-14
WebFluxAnnotationAutoConfiguration.java
...gure/web/reactive/WebFluxAnnotationAutoConfiguration.java
+171
-9
WebMvcAutoConfiguration.java
...ot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java
+168
-11
SpringBootWebSecurityConfigurationTests.java
...ure/security/SpringBootWebSecurityConfigurationTests.java
+4
-3
DelegatingValidatorTests.java
...ot/autoconfigure/validation/DelegatingValidatorTests.java
+116
-0
SpringValidatorTests.java
...k/boot/autoconfigure/validation/SpringValidatorTests.java
+0
-151
ValidationAutoConfigurationTests.java
...onfigure/validation/ValidationAutoConfigurationTests.java
+115
-37
WebFluxAnnotationAutoConfigurationTests.java
...web/reactive/WebFluxAnnotationAutoConfigurationTests.java
+194
-65
WebMvcAutoConfigurationTests.java
...toconfigure/web/servlet/WebMvcAutoConfigurationTests.java
+182
-62
BasicErrorControllerDirectMockMvcTests.java
...servlet/error/BasicErrorControllerDirectMockMvcTests.java
+4
-3
BasicErrorControllerMockMvcTests.java
...e/web/servlet/error/BasicErrorControllerMockMvcTests.java
+4
-3
OptionSetGroovyCompilerConfiguration.java
...command/options/OptionSetGroovyCompilerConfiguration.java
+5
-0
RunCommand.java
.../org/springframework/boot/cli/command/run/RunCommand.java
+6
-1
GroovyCompiler.java
...org/springframework/boot/cli/compiler/GroovyCompiler.java
+2
-1
GroovyCompilerConfiguration.java
...mework/boot/cli/compiler/GroovyCompilerConfiguration.java
+6
-0
AetherGrapeEngine.java
...gframework/boot/cli/compiler/grape/AetherGrapeEngine.java
+7
-5
AetherGrapeEngineFactory.java
...ork/boot/cli/compiler/grape/AetherGrapeEngineFactory.java
+2
-8
GroovyGrabDependencyResolverTests.java
...li/command/install/GroovyGrabDependencyResolverTests.java
+5
-0
AetherGrapeEngineTests.java
...ework/boot/cli/compiler/grape/AetherGrapeEngineTests.java
+1
-1
appendix-executable-jar-format.adoc
...ocs/src/main/asciidoc/appendix-executable-jar-format.adoc
+2
-0
SpringBootTestContextBootstrapper.java
.../boot/test/context/SpringBootTestContextBootstrapper.java
+1
-2
SpringBootTestContextBootstrapperWithInitializersTests.java
...ringBootTestContextBootstrapperWithInitializersTests.java
+66
-0
PropertiesLauncher.java
...a/org/springframework/boot/loader/PropertiesLauncher.java
+55
-22
PropertiesLauncherTests.java
.../springframework/boot/loader/PropertiesLauncherTests.java
+78
-4
app.jar
...spring-boot-loader/src/test/resources/nested-jars/app.jar
+0
-0
No files found.
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointMvcIntegrationTests.java
View file @
81fef71f
...
...
@@ -42,6 +42,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
;
import
org.springframework.boot.autoconfigure.http.HttpMessageConverters
;
import
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
;
import
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
;
...
...
@@ -85,15 +86,16 @@ public class EndpointMvcIntegrationTests {
@Test
public
void
envEndpointNotHidden
()
throws
InterruptedException
{
String
body
=
new
TestRestTemplate
().
getForObject
(
"http://localhost:"
+
this
.
port
+
"/application/env/foo.bar"
,
String
.
class
);
"http://localhost:"
+
this
.
port
+
"/application/env/foo.bar"
,
String
.
class
);
assertThat
(
body
).
isNotNull
().
contains
(
"\"baz\""
);
assertThat
(
this
.
interceptor
.
invoked
()).
isTrue
();
}
@Test
public
void
healthEndpointNotHidden
()
throws
InterruptedException
{
String
body
=
new
TestRestTemplate
()
.
getForObject
(
"http://localhost:"
+
this
.
port
+
"/application/health"
,
String
.
class
);
String
body
=
new
TestRestTemplate
()
.
getForObject
(
"http://localhost:"
+
this
.
port
+
"/application/health"
,
String
.
class
);
assertThat
(
body
).
isNotNull
().
contains
(
"status"
);
assertThat
(
this
.
interceptor
.
invoked
()).
isTrue
();
}
...
...
@@ -153,9 +155,9 @@ public class EndpointMvcIntegrationTests {
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@Import
({
ServletWebServerFactoryAutoConfiguration
.
class
,
DispatcherServletAutoConfiguration
.
class
,
WebMvc
AutoConfiguration
.
class
,
JacksonAutoConfiguration
.
class
,
ErrorMvc
AutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
DispatcherServletAutoConfiguration
.
class
,
Validation
AutoConfiguration
.
class
,
WebMvcAutoConfiguration
.
class
,
Jackson
AutoConfiguration
.
class
,
ErrorMvcAutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
protected
@interface
MinimalWebConfiguration
{
}
...
...
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/DefaultValidatorConfiguration.java
0 → 100644
View file @
81fef71f
/*
* 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
.
validation
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.validation.MessageInterpolatorFactory
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Role
;
import
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
;
/**
* Default validator configuration imported by {@link ValidationAutoConfiguration}.
*
* @author Stephane Nicoll
* @author Phillip Webb
*/
@Configuration
class
DefaultValidatorConfiguration
{
@Bean
@ConditionalOnMissingBean
(
type
=
{
"javax.validation.Validator"
,
"org.springframework.validation.Validator"
})
@Role
(
BeanDefinition
.
ROLE_INFRASTRUCTURE
)
public
static
LocalValidatorFactoryBean
defaultValidator
()
{
LocalValidatorFactoryBean
factoryBean
=
new
LocalValidatorFactoryBean
();
MessageInterpolatorFactory
interpolatorFactory
=
new
MessageInterpolatorFactory
();
factoryBean
.
setMessageInterpolator
(
interpolatorFactory
.
getObject
());
return
factoryBean
;
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/DelegatingValidator.java
0 → 100644
View file @
81fef71f
/*
* 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
.
validation
;
import
org.springframework.util.Assert
;
import
org.springframework.validation.Errors
;
import
org.springframework.validation.SmartValidator
;
import
org.springframework.validation.Validator
;
import
org.springframework.validation.beanvalidation.SpringValidatorAdapter
;
/**
* {@link Validator} implementation that delegates calls to another {@link Validator}.
* This {@link Validator} implements Spring's {@link SmartValidator} interface but does
* not implement the JSR-303 {@code javax.validator.Validator} interface.
*
* @author Phillip Webb
* @since 1.5.3
*/
public
class
DelegatingValidator
implements
SmartValidator
{
private
final
Validator
delegate
;
/**
* Create a new {@link DelegatingValidator} instance.
* @param targetValidator the target JSR validator
*/
public
DelegatingValidator
(
javax
.
validation
.
Validator
targetValidator
)
{
this
.
delegate
=
new
SpringValidatorAdapter
(
targetValidator
);
}
/**
* Create a new {@link DelegatingValidator} instance.
* @param targetValidator the target validator
*/
public
DelegatingValidator
(
Validator
targetValidator
)
{
Assert
.
notNull
(
targetValidator
,
"Target Validator must not be null"
);
this
.
delegate
=
targetValidator
;
}
@Override
public
boolean
supports
(
Class
<?>
clazz
)
{
return
this
.
delegate
.
supports
(
clazz
);
}
@Override
public
void
validate
(
Object
target
,
Errors
errors
)
{
this
.
delegate
.
validate
(
target
,
errors
);
}
@Override
public
void
validate
(
Object
target
,
Errors
errors
,
Object
...
validationHints
)
{
if
(
this
.
delegate
instanceof
SmartValidator
)
{
((
SmartValidator
)
this
.
delegate
).
validate
(
target
,
errors
,
validationHints
);
}
else
{
this
.
delegate
.
validate
(
target
,
errors
);
}
}
/**
* Return the delegate validator.
* @return the delegate validator
*/
protected
final
Validator
getDelegate
()
{
return
this
.
delegate
;
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/Jsr303ValidatorAdapterConfiguration.java
0 → 100644
View file @
81fef71f
/*
* 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
.
validation
;
import
javax.validation.Validator
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Role
;
import
org.springframework.validation.SmartValidator
;
/**
* JSR 303 adapter configration imported by {@link ValidationAutoConfiguration}.
*
* @author Stephane Nicoll
* @author Phillip Webb
*/
@Configuration
class
Jsr303ValidatorAdapterConfiguration
{
@Bean
@ConditionalOnSingleCandidate
(
Validator
.
class
)
@ConditionalOnMissingBean
(
org
.
springframework
.
validation
.
Validator
.
class
)
@Role
(
BeanDefinition
.
ROLE_INFRASTRUCTURE
)
public
SmartValidator
jsr303ValidatorAdapter
(
Validator
validator
)
{
return
new
DelegatingValidator
(
validator
);
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/SpringValidator.java
deleted
100644 → 0
View file @
359854eb
/*
* 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
.
validation
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.DisposableBean
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.NoSuchBeanDefinitionException
;
import
org.springframework.boot.validation.MessageInterpolatorFactory
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.validation.Errors
;
import
org.springframework.validation.SmartValidator
;
import
org.springframework.validation.Validator
;
import
org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean
;
import
org.springframework.validation.beanvalidation.SpringValidatorAdapter
;
/**
* A {@link SmartValidator} exposed as a bean for WebMvc use. Wraps existing
* {@link SpringValidatorAdapter} instances so that only the Spring's {@link Validator}
* type is exposed. This prevents such a bean to expose both the Spring and JSR-303
* validator contract at the same time.
*
* @author Stephane Nicoll
* @author Phillip Webb
* @since 2.0.0
*/
public
class
SpringValidator
implements
SmartValidator
,
ApplicationContextAware
,
InitializingBean
,
DisposableBean
{
private
final
SpringValidatorAdapter
target
;
private
final
boolean
existingBean
;
public
SpringValidator
(
SpringValidatorAdapter
target
,
boolean
existingBean
)
{
this
.
target
=
target
;
this
.
existingBean
=
existingBean
;
}
public
final
SpringValidatorAdapter
getTarget
()
{
return
this
.
target
;
}
@Override
public
boolean
supports
(
Class
<?>
clazz
)
{
return
this
.
target
.
supports
(
clazz
);
}
@Override
public
void
validate
(
Object
target
,
Errors
errors
)
{
this
.
target
.
validate
(
target
,
errors
);
}
@Override
public
void
validate
(
Object
target
,
Errors
errors
,
Object
...
validationHints
)
{
this
.
target
.
validate
(
target
,
errors
,
validationHints
);
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
if
(!
this
.
existingBean
&&
this
.
target
instanceof
ApplicationContextAware
)
{
((
ApplicationContextAware
)
this
.
target
)
.
setApplicationContext
(
applicationContext
);
}
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
if
(!
this
.
existingBean
&&
this
.
target
instanceof
InitializingBean
)
{
((
InitializingBean
)
this
.
target
).
afterPropertiesSet
();
}
}
@Override
public
void
destroy
()
throws
Exception
{
if
(!
this
.
existingBean
&&
this
.
target
instanceof
DisposableBean
)
{
((
DisposableBean
)
this
.
target
).
destroy
();
}
}
public
static
Validator
get
(
ApplicationContext
applicationContext
,
Validator
validator
)
{
if
(
validator
!=
null
)
{
return
wrap
(
validator
,
false
);
}
return
getExistingOrCreate
(
applicationContext
);
}
private
static
Validator
getExistingOrCreate
(
ApplicationContext
applicationContext
)
{
Validator
existing
=
getExisting
(
applicationContext
);
if
(
existing
!=
null
)
{
return
wrap
(
existing
,
true
);
}
return
create
();
}
private
static
Validator
getExisting
(
ApplicationContext
applicationContext
)
{
try
{
javax
.
validation
.
Validator
validator
=
applicationContext
.
getBean
(
javax
.
validation
.
Validator
.
class
);
if
(
validator
instanceof
Validator
)
{
return
(
Validator
)
validator
;
}
return
new
SpringValidatorAdapter
(
validator
);
}
catch
(
NoSuchBeanDefinitionException
ex
)
{
return
null
;
}
}
private
static
Validator
create
()
{
OptionalValidatorFactoryBean
validator
=
new
OptionalValidatorFactoryBean
();
validator
.
setMessageInterpolator
(
new
MessageInterpolatorFactory
().
getObject
());
return
wrap
(
validator
,
false
);
}
private
static
Validator
wrap
(
Validator
validator
,
boolean
existingBean
)
{
if
(
validator
instanceof
javax
.
validation
.
Validator
)
{
if
(
validator
instanceof
SpringValidatorAdapter
)
{
return
new
SpringValidator
((
SpringValidatorAdapter
)
validator
,
existingBean
);
}
return
new
SpringValidator
(
new
SpringValidatorAdapter
((
javax
.
validation
.
Validator
)
validator
),
existingBean
);
}
return
validator
;
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.java
View file @
81fef71f
...
...
@@ -19,18 +19,16 @@ package org.springframework.boot.autoconfigure.validation;
import
javax.validation.Validator
;
import
javax.validation.executable.ExecutableValidator
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
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.autoconfigure.condition.ConditionalOnResource
;
import
org.springframework.boot.bind.RelaxedPropertyResolver
;
import
org.springframework.boot.validation.MessageInterpolatorFactory
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.
Role
;
import
org.springframework.context.annotation.
Import
;
import
org.springframework.core.env.Environment
;
import
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
;
import
org.springframework.validation.beanvalidation.MethodValidationPostProcessor
;
/**
...
...
@@ -43,19 +41,12 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess
@Configuration
@ConditionalOnClass
(
ExecutableValidator
.
class
)
@ConditionalOnResource
(
resources
=
"classpath:META-INF/services/javax.validation.spi.ValidationProvider"
)
@Import
({
DefaultValidatorConfiguration
.
class
,
Jsr303ValidatorAdapterConfiguration
.
class
})
public
class
ValidationAutoConfiguration
{
@Bean
@Role
(
BeanDefinition
.
ROLE_INFRASTRUCTURE
)
@ConditionalOnMissingBean
public
static
Validator
jsr303Validator
()
{
LocalValidatorFactoryBean
factoryBean
=
new
LocalValidatorFactoryBean
();
MessageInterpolatorFactory
interpolatorFactory
=
new
MessageInterpolatorFactory
();
factoryBean
.
setMessageInterpolator
(
interpolatorFactory
.
getObject
());
return
factoryBean
;
}
@Bean
@ConditionalOnBean
(
Validator
.
class
)
@ConditionalOnMissingBean
public
static
MethodValidationPostProcessor
methodValidationPostProcessor
(
Environment
environment
,
Validator
validator
)
{
...
...
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAnnotationAutoConfiguration.java
View file @
81fef71f
...
...
@@ -23,30 +23,50 @@ import java.util.concurrent.TimeUnit;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.BeanFactoryUtils
;
import
org.springframework.beans.factory.DisposableBean
;
import
org.springframework.beans.factory.InitializingBean
;
import
org.springframework.beans.factory.ListableBeanFactory
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.BeanFactoryPostProcessor
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistry
;
import
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.AutoConfigureOrder
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
;
import
org.springframework.boot.autoconfigure.validation.
Spr
ingValidator
;
import
org.springframework.boot.autoconfigure.validation.
Delegat
ingValidator
;
import
org.springframework.boot.autoconfigure.web.ConditionalOnEnabledResourceChain
;
import
org.springframework.boot.autoconfigure.web.ResourceProperties
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.ConditionContext
;
import
org.springframework.context.annotation.Conditional
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.ConfigurationCondition
;
import
org.springframework.context.annotation.Import
;
import
org.springframework.context.annotation.Role
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.annotation.AnnotationAwareOrderComparator
;
import
org.springframework.core.annotation.Order
;
import
org.springframework.core.convert.converter.Converter
;
import
org.springframework.core.convert.converter.GenericConverter
;
import
org.springframework.core.type.AnnotatedTypeMetadata
;
import
org.springframework.format.Formatter
;
import
org.springframework.format.FormatterRegistry
;
import
org.springframework.http.CacheControl
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.validation.Validator
;
import
org.springframework.web.reactive.config.DelegatingWebFluxConfiguration
;
import
org.springframework.web.reactive.config.EnableWebFlux
;
...
...
@@ -82,6 +102,12 @@ import org.springframework.web.reactive.result.view.ViewResolver;
@AutoConfigureOrder
(
Ordered
.
HIGHEST_PRECEDENCE
+
10
)
public
class
WebFluxAnnotationAutoConfiguration
{
@Bean
@Role
(
BeanDefinition
.
ROLE_INFRASTRUCTURE
)
public
static
WebFluxValidatorPostProcessor
mvcValidatorAliasPostProcessor
()
{
return
new
WebFluxValidatorPostProcessor
();
}
@Configuration
@EnableConfigurationProperties
({
ResourceProperties
.
class
,
WebFluxProperties
.
class
})
@Import
(
EnableWebFluxConfiguration
.
class
)
...
...
@@ -190,17 +216,29 @@ public class WebFluxAnnotationAutoConfiguration {
* Configuration equivalent to {@code @EnableWebFlux}.
*/
@Configuration
public
static
class
EnableWebFluxConfiguration
extends
DelegatingWebFluxConfiguration
{
public
static
class
EnableWebFluxConfiguration
extends
DelegatingWebFluxConfiguration
implements
InitializingBean
{
private
final
ApplicationContext
context
;
public
EnableWebFluxConfiguration
(
ApplicationContext
context
)
{
this
.
context
=
context
;
}
@Override
@Bean
@Override
@Conditional
(
DisableWebFluxValidatorCondition
.
class
)
public
Validator
webFluxValidator
()
{
if
(!
ClassUtils
.
isPresent
(
"javax.validation.Validator"
,
getClass
().
getClassLoader
()))
{
return
super
.
webFluxValidator
();
}
return
SpringValidator
.
get
(
getApplicationContext
(),
getValidator
());
return
this
.
context
.
getBean
(
"webFluxValidator"
,
Validator
.
class
);
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
Assert
.
state
(
getValidator
()
==
null
,
"Found unexpected validator configuration. A Spring Boot WebFlux "
+
"validator should be registered as bean named "
+
"'webFluxValidator' and not returned from "
+
"WebFluxConfigurer.getValidator()"
);
}
}
...
...
@@ -266,4 +304,128 @@ public class WebFluxAnnotationAutoConfiguration {
}
/**
* Condition used to disable the default WebFlux validator registration. The
* {@link WebFluxValidatorPostProcessor} is used to configure the
* {@code webFluxValidator} bean.
*/
static
class
DisableWebFluxValidatorCondition
implements
ConfigurationCondition
{
@Override
public
ConfigurationPhase
getConfigurationPhase
()
{
return
ConfigurationPhase
.
REGISTER_BEAN
;
}
@Override
public
boolean
matches
(
ConditionContext
context
,
AnnotatedTypeMetadata
metadata
)
{
return
false
;
}
}
/**
* {@link BeanFactoryPostProcessor} to deal with the MVC validator bean registration.
* Applies the following rules:
* <ul>
* <li>With no validators - Uses standard
* {@link WebFluxConfigurationSupport#webFluxValidator()} logic.</li>
* <li>With a single validator - Uses an alias.</li>
* <li>With multiple validators - Registers a mvcValidator bean if not already
* defined.</li>
* </ul>
*/
@Order
(
Ordered
.
LOWEST_PRECEDENCE
)
static
class
WebFluxValidatorPostProcessor
implements
BeanDefinitionRegistryPostProcessor
{
private
static
final
String
JSR303_VALIDATOR_CLASS
=
"javax.validation.Validator"
;
@Override
public
void
postProcessBeanDefinitionRegistry
(
BeanDefinitionRegistry
registry
)
throws
BeansException
{
if
(
registry
instanceof
ListableBeanFactory
)
{
postProcess
(
registry
,
(
ListableBeanFactory
)
registry
);
}
}
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
}
private
void
postProcess
(
BeanDefinitionRegistry
registry
,
ListableBeanFactory
beanFactory
)
{
String
[]
validatorBeans
=
BeanFactoryUtils
.
beanNamesForTypeIncludingAncestors
(
beanFactory
,
Validator
.
class
,
false
,
false
);
if
(
validatorBeans
.
length
==
0
)
{
registerMvcValidator
(
registry
,
beanFactory
);
}
else
if
(
validatorBeans
.
length
==
1
)
{
registry
.
registerAlias
(
validatorBeans
[
0
],
"webFluxValidator"
);
}
else
{
if
(!
ObjectUtils
.
containsElement
(
validatorBeans
,
"webFluxValidator"
))
{
registerMvcValidator
(
registry
,
beanFactory
);
}
}
}
private
void
registerMvcValidator
(
BeanDefinitionRegistry
registry
,
ListableBeanFactory
beanFactory
)
{
RootBeanDefinition
definition
=
new
RootBeanDefinition
();
definition
.
setBeanClass
(
getClass
());
definition
.
setFactoryMethodName
(
"webFluxValidator"
);
registry
.
registerBeanDefinition
(
"webFluxValidator"
,
definition
);
}
static
Validator
webFluxValidator
()
{
Validator
validator
=
new
WebFluxConfigurationSupport
().
webFluxValidator
();
try
{
if
(
ClassUtils
.
forName
(
JSR303_VALIDATOR_CLASS
,
null
)
.
isInstance
(
validator
))
{
return
new
DelegatingWebFluxValidator
(
validator
);
}
}
catch
(
Exception
ex
)
{
}
return
validator
;
}
}
/**
* {@link DelegatingValidator} for the WebFlux validator.
*/
static
class
DelegatingWebFluxValidator
extends
DelegatingValidator
implements
ApplicationContextAware
,
InitializingBean
,
DisposableBean
{
DelegatingWebFluxValidator
(
Validator
targetValidator
)
{
super
(
targetValidator
);
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
if
(
getDelegate
()
instanceof
ApplicationContextAware
)
{
((
ApplicationContextAware
)
getDelegate
())
.
setApplicationContext
(
applicationContext
);
}
}
@Override
public
void
afterPropertiesSet
()
throws
Exception
{
if
(
getDelegate
()
instanceof
InitializingBean
)
{
((
InitializingBean
)
getDelegate
()).
afterPropertiesSet
();
}
}
@Override
public
void
destroy
()
throws
Exception
{
if
(
getDelegate
()
instanceof
DisposableBean
)
{
((
DisposableBean
)
getDelegate
()).
destroy
();
}
}
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java
View file @
81fef71f
This diff is collapsed.
Click to expand it.
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SpringBootWebSecurityConfigurationTests.java
View file @
81fef71f
...
...
@@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
;
import
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
;
import
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
;
...
...
@@ -322,9 +323,9 @@ public class SpringBootWebSecurityConfigurationTests {
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@Import
({
ServletWebServerFactoryAutoConfiguration
.
class
,
DispatcherServletAutoConfiguration
.
class
,
WebMvc
AutoConfiguration
.
class
,
HttpMessageConvertersAutoConfiguration
.
class
,
ErrorMvc
AutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
DispatcherServletAutoConfiguration
.
class
,
Validation
AutoConfiguration
.
class
,
WebMvcAutoConfiguration
.
class
,
HttpMessageConverters
AutoConfiguration
.
class
,
ErrorMvcAutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
protected
@interface
MinimalWebConfiguration
{
}
...
...
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/DelegatingValidatorTests.java
0 → 100644
View file @
81fef71f
/*
* 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
.
validation
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.ExpectedException
;
import
org.mockito.Mock
;
import
org.mockito.MockitoAnnotations
;
import
org.springframework.validation.BeanPropertyBindingResult
;
import
org.springframework.validation.Errors
;
import
org.springframework.validation.SmartValidator
;
import
org.springframework.validation.Validator
;
import
static
org
.
mockito
.
Matchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
verify
;
/**
* Tests for {@link DelegatingValidator}.
*
* @author Phillip Webb
*/
public
class
DelegatingValidatorTests
{
@Rule
public
ExpectedException
thrown
=
ExpectedException
.
none
();
@Mock
private
SmartValidator
delegate
;
private
DelegatingValidator
delegating
;
@Before
public
void
setup
()
{
MockitoAnnotations
.
initMocks
(
this
);
this
.
delegating
=
new
DelegatingValidator
(
this
.
delegate
);
}
@Test
public
void
createWhenJsrValidatorIsNullShouldThrowException
()
throws
Exception
{
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"Target Validator must not be null"
);
new
DelegatingValidator
((
javax
.
validation
.
Validator
)
null
);
}
@Test
public
void
createWithJsrValidatorShouldAdapt
()
throws
Exception
{
javax
.
validation
.
Validator
delegate
=
mock
(
javax
.
validation
.
Validator
.
class
);
Validator
delegating
=
new
DelegatingValidator
(
delegate
);
Object
target
=
new
Object
();
Errors
errors
=
new
BeanPropertyBindingResult
(
target
,
"foo"
);
delegating
.
validate
(
target
,
errors
);
verify
(
delegate
).
validate
(
any
());
}
@Test
public
void
createWithSpringValidatorWhenValidatorIsNullShouldThrowException
()
throws
Exception
{
this
.
thrown
.
expect
(
IllegalArgumentException
.
class
);
this
.
thrown
.
expectMessage
(
"Target Validator must not be null"
);
new
DelegatingValidator
((
Validator
)
null
);
}
@Test
public
void
supportsShouldDelegateToValidator
()
throws
Exception
{
this
.
delegating
.
supports
(
Object
.
class
);
verify
(
this
.
delegate
).
supports
(
Object
.
class
);
}
@Test
public
void
validateShouldDelegateToValidator
()
throws
Exception
{
Object
target
=
new
Object
();
Errors
errors
=
new
BeanPropertyBindingResult
(
target
,
"foo"
);
this
.
delegating
.
validate
(
target
,
errors
);
verify
(
this
.
delegate
).
validate
(
target
,
errors
);
}
@Test
public
void
validateWithHintsShouldDelegateToValidator
()
throws
Exception
{
Object
target
=
new
Object
();
Errors
errors
=
new
BeanPropertyBindingResult
(
target
,
"foo"
);
Object
[]
hints
=
{
"foo"
,
"bar"
};
this
.
delegating
.
validate
(
target
,
errors
,
hints
);
verify
(
this
.
delegate
).
validate
(
target
,
errors
,
hints
);
}
@Test
public
void
validateWithHintsWhenDelegateIsNotSmartShouldDelegateToSimpleValidator
()
throws
Exception
{
Validator
delegate
=
mock
(
Validator
.
class
);
DelegatingValidator
delegating
=
new
DelegatingValidator
(
delegate
);
Object
target
=
new
Object
();
Errors
errors
=
new
BeanPropertyBindingResult
(
target
,
"foo"
);
Object
[]
hints
=
{
"foo"
,
"bar"
};
delegating
.
validate
(
target
,
errors
,
hints
);
verify
(
delegate
).
validate
(
target
,
errors
);
}
}
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/SpringValidatorTests.java
deleted
100644 → 0
View file @
359854eb
/*
* 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
.
validation
;
import
java.util.HashMap
;
import
javax.validation.constraints.Min
;
import
org.junit.After
;
import
org.junit.Test
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.validation.MapBindingResult
;
import
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
times
;
import
static
org
.
mockito
.
Mockito
.
verify
;
/**
* Tests for {@link SpringValidator}.
*
* @author Stephane Nicoll
*/
public
class
SpringValidatorTests
{
private
AnnotationConfigApplicationContext
context
;
@After
public
void
close
()
{
if
(
this
.
context
!=
null
)
{
this
.
context
.
close
();
}
}
@Test
public
void
wrapLocalValidatorFactoryBean
()
{
SpringValidator
wrapper
=
load
(
LocalValidatorFactoryBeanConfig
.
class
);
assertThat
(
wrapper
.
supports
(
SampleData
.
class
)).
isTrue
();
MapBindingResult
errors
=
new
MapBindingResult
(
new
HashMap
<
String
,
Object
>(),
"test"
);
wrapper
.
validate
(
new
SampleData
(
40
),
errors
);
assertThat
(
errors
.
getErrorCount
()).
isEqualTo
(
1
);
}
@Test
public
void
wrapperInvokesCallbackOnNonManagedBean
()
{
load
(
NonManagedBeanConfig
.
class
);
LocalValidatorFactoryBean
validator
=
this
.
context
.
getBean
(
NonManagedBeanConfig
.
class
).
validator
;
verify
(
validator
,
times
(
1
)).
setApplicationContext
(
any
(
ApplicationContext
.
class
));
verify
(
validator
,
times
(
1
)).
afterPropertiesSet
();
verify
(
validator
,
times
(
0
)).
destroy
();
this
.
context
.
close
();
this
.
context
=
null
;
verify
(
validator
,
times
(
1
)).
destroy
();
}
@Test
public
void
wrapperDoesNotInvokeCallbackOnManagedBean
()
{
load
(
ManagedBeanConfig
.
class
);
LocalValidatorFactoryBean
validator
=
this
.
context
.
getBean
(
ManagedBeanConfig
.
class
).
validator
;
verify
(
validator
,
times
(
0
)).
setApplicationContext
(
any
(
ApplicationContext
.
class
));
verify
(
validator
,
times
(
0
)).
afterPropertiesSet
();
verify
(
validator
,
times
(
0
)).
destroy
();
this
.
context
.
close
();
this
.
context
=
null
;
verify
(
validator
,
times
(
0
)).
destroy
();
}
private
SpringValidator
load
(
Class
<?>
config
)
{
AnnotationConfigApplicationContext
ctx
=
new
AnnotationConfigApplicationContext
();
ctx
.
register
(
config
);
ctx
.
refresh
();
this
.
context
=
ctx
;
return
this
.
context
.
getBean
(
SpringValidator
.
class
);
}
@Configuration
static
class
LocalValidatorFactoryBeanConfig
{
@Bean
public
LocalValidatorFactoryBean
validator
()
{
return
new
LocalValidatorFactoryBean
();
}
@Bean
public
SpringValidator
wrapper
()
{
return
new
SpringValidator
(
validator
(),
true
);
}
}
@Configuration
static
class
NonManagedBeanConfig
{
private
final
LocalValidatorFactoryBean
validator
=
mock
(
LocalValidatorFactoryBean
.
class
);
@Bean
public
SpringValidator
wrapper
()
{
return
new
SpringValidator
(
this
.
validator
,
false
);
}
}
@Configuration
static
class
ManagedBeanConfig
{
private
final
LocalValidatorFactoryBean
validator
=
mock
(
LocalValidatorFactoryBean
.
class
);
@Bean
public
SpringValidator
wrapper
()
{
return
new
SpringValidator
(
this
.
validator
,
true
);
}
}
static
class
SampleData
{
@Min
(
42
)
private
int
counter
;
SampleData
(
int
counter
)
{
this
.
counter
=
counter
;
}
}
}
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/validation/ValidationAutoConfigurationTests.java
View file @
81fef71f
...
...
@@ -32,9 +32,12 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
;
import
org.springframework.validation.beanvalidation.MethodValidationPostProcessor
;
import
org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* Tests for {@link ValidationAutoConfiguration}.
...
...
@@ -56,45 +59,94 @@ public class ValidationAutoConfigurationTests {
}
@Test
public
void
validationIsEnabled
()
{
load
(
SampleService
.
class
);
public
void
validationAutoConfigurationShouldConfigureJsrAndSpringValidator
()
throws
Exception
{
load
(
Config
.
class
);
Validator
jsrValidator
=
this
.
context
.
getBean
(
Validator
.
class
);
String
[]
jsrValidatorNames
=
this
.
context
.
getBeanNamesForType
(
Validator
.
class
);
org
.
springframework
.
validation
.
Validator
springValidator
=
this
.
context
.
getBean
(
org
.
springframework
.
validation
.
Validator
.
class
);
String
[]
springValidatorNames
=
this
.
context
.
getBeanNamesForType
(
org
.
springframework
.
validation
.
Validator
.
class
);
assertThat
(
jsrValidator
).
isInstanceOf
(
LocalValidatorFactoryBean
.
class
);
assertThat
(
jsrValidator
).
isEqualTo
(
springValidator
);
assertThat
(
jsrValidatorNames
).
containsExactly
(
"defaultValidator"
);
assertThat
(
springValidatorNames
).
containsExactly
(
"defaultValidator"
);
}
@Test
public
void
validationAutoConfigurationWhenUserProvidesValidatorShouldBackOff
()
throws
Exception
{
load
(
UserDefinedValidatorConfig
.
class
);
Validator
jsrValidator
=
this
.
context
.
getBean
(
Validator
.
class
);
String
[]
jsrValidatorNames
=
this
.
context
.
getBeanNamesForType
(
Validator
.
class
);
org
.
springframework
.
validation
.
Validator
springValidator
=
this
.
context
.
getBean
(
org
.
springframework
.
validation
.
Validator
.
class
);
String
[]
springValidatorNames
=
this
.
context
.
getBeanNamesForType
(
org
.
springframework
.
validation
.
Validator
.
class
);
assertThat
(
jsrValidator
).
isInstanceOf
(
OptionalValidatorFactoryBean
.
class
);
assertThat
(
jsrValidator
).
isEqualTo
(
springValidator
);
assertThat
(
jsrValidatorNames
).
containsExactly
(
"customValidator"
);
assertThat
(
springValidatorNames
).
containsExactly
(
"customValidator"
);
}
@Test
public
void
validationAutoConfigurationWhenUserProvidesJsrOnlyShouldAdaptIt
()
throws
Exception
{
load
(
UserDefinedJsrValidatorConfig
.
class
);
Validator
jsrValidator
=
this
.
context
.
getBean
(
Validator
.
class
);
String
[]
jsrValidatorNames
=
this
.
context
.
getBeanNamesForType
(
Validator
.
class
);
org
.
springframework
.
validation
.
Validator
springValidator
=
this
.
context
.
getBean
(
org
.
springframework
.
validation
.
Validator
.
class
);
String
[]
springValidatorNames
=
this
.
context
.
getBeanNamesForType
(
org
.
springframework
.
validation
.
Validator
.
class
);
assertThat
(
jsrValidator
).
isNotEqualTo
(
springValidator
);
assertThat
(
springValidator
).
isInstanceOf
(
DelegatingValidator
.
class
);
assertThat
(
jsrValidatorNames
).
containsExactly
(
"customValidator"
);
assertThat
(
springValidatorNames
).
containsExactly
(
"jsr303ValidatorAdapter"
);
}
@Test
public
void
validationAutoConfigurationShouldBeEnabled
()
{
load
(
ClassWithConstraint
.
class
);
assertThat
(
this
.
context
.
getBeansOfType
(
Validator
.
class
)).
hasSize
(
1
);
SampleService
service
=
this
.
context
.
getBean
(
SampleService
.
class
);
service
.
doSomething
(
"Valid"
);
ClassWithConstraint
service
=
this
.
context
.
getBean
(
ClassWithConstraint
.
class
);
service
.
call
(
"Valid"
);
this
.
thrown
.
expect
(
ConstraintViolationException
.
class
);
service
.
doSomething
(
"KO"
);
service
.
call
(
"KO"
);
}
@Test
public
void
validation
Uses
CglibProxy
()
{
load
(
DefaultAnotherSampleService
.
class
);
public
void
validation
AutoConfigurationShouldUse
CglibProxy
()
{
load
(
ImplementationOfInterfaceWithConstraint
.
class
);
assertThat
(
this
.
context
.
getBeansOfType
(
Validator
.
class
)).
hasSize
(
1
);
DefaultAnotherSampleService
service
=
this
.
context
.
getBean
(
DefaultAnotherSampleService
.
class
);
service
.
doSomething
(
42
);
ImplementationOfInterfaceWithConstraint
service
=
this
.
context
.
getBean
(
ImplementationOfInterfaceWithConstraint
.
class
);
service
.
call
(
42
);
this
.
thrown
.
expect
(
ConstraintViolationException
.
class
);
service
.
doSomething
(
2
);
service
.
call
(
2
);
}
@Test
public
void
validation
CanBeConfiguredTo
UseJdkProxy
()
{
public
void
validation
AutoConfigurationWhenProxyTargetClassIsFalseShould
UseJdkProxy
()
{
load
(
AnotherSampleServiceConfiguration
.
class
,
"spring.aop.proxy-target-class=false"
);
assertThat
(
this
.
context
.
getBeansOfType
(
Validator
.
class
)).
hasSize
(
1
);
assertThat
(
this
.
context
.
getBeansOfType
(
DefaultAnotherSampleService
.
class
))
.
isEmpty
();
AnotherSampleService
service
=
this
.
context
.
getBean
(
AnotherSampleService
.
class
);
service
.
doSomething
(
42
);
assertThat
(
this
.
context
.
getBeansOfType
(
ImplementationOfInterfaceWithConstraint
.
class
)).
isEmpty
();
InterfaceWithConstraint
service
=
this
.
context
.
getBean
(
InterfaceWithConstraint
.
class
);
service
.
call
(
42
);
this
.
thrown
.
expect
(
ConstraintViolationException
.
class
);
service
.
doSomething
(
2
);
service
.
call
(
2
);
}
@Test
public
void
userDefinedMethodValidationPostProcessorTakesPrecedence
()
{
load
(
SampleConfiguration
.
class
);
public
void
validationAutoConfigurationWhenUserDefinesMethodValidationPostProcessorShouldBackOff
()
{
load
(
UserDefinedMethodValidationConfig
.
class
);
assertThat
(
this
.
context
.
getBeansOfType
(
Validator
.
class
)).
hasSize
(
1
);
Object
userMethodValidationPostProcessor
=
this
.
context
.
getBean
(
"
test
MethodValidationPostProcessor"
);
.
getBean
(
"
custom
MethodValidationPostProcessor"
);
assertThat
(
this
.
context
.
getBean
(
MethodValidationPostProcessor
.
class
))
.
isSameAs
(
userMethodValidationPostProcessor
);
assertThat
(
this
.
context
.
getBeansOfType
(
MethodValidationPostProcessor
.
class
))
...
...
@@ -115,47 +167,73 @@ public class ValidationAutoConfigurationTests {
this
.
context
=
ctx
;
}
@
Validated
static
class
SampleService
{
@
Configuration
static
class
Config
{
public
void
doSomething
(
@Size
(
min
=
3
,
max
=
10
)
String
name
)
{
}
@Configuration
static
class
UserDefinedValidatorConfig
{
@Bean
public
OptionalValidatorFactoryBean
customValidator
()
{
return
new
OptionalValidatorFactoryBean
();
}
}
interface
AnotherSampleService
{
@Configuration
static
class
UserDefinedJsrValidatorConfig
{
@Bean
public
Validator
customValidator
()
{
return
mock
(
Validator
.
class
);
}
void
doSomething
(
@Min
(
42
)
Integer
counter
);
}
@Validated
static
class
DefaultAnotherSampleService
implements
AnotherSampleService
{
@Override
public
void
doSomething
(
Integer
counter
)
{
@Configuration
static
class
UserDefinedMethodValidationConfig
{
@Bean
public
MethodValidationPostProcessor
customMethodValidationPostProcessor
()
{
return
new
MethodValidationPostProcessor
();
}
}
@Configuration
static
class
AnotherSampleServiceConfiguration
{
@Bean
public
AnotherSampleService
anotherSampleService
()
{
return
new
DefaultAnotherSampleService
();
public
InterfaceWithConstraint
implementationOfInterfaceWithConstraint
()
{
return
new
ImplementationOfInterfaceWithConstraint
();
}
}
@Configuration
static
class
SampleConfiguration
{
@Validated
static
class
ClassWithConstraint
{
public
void
call
(
@Size
(
min
=
3
,
max
=
10
)
String
name
)
{
@Bean
public
MethodValidationPostProcessor
testMethodValidationPostProcessor
()
{
return
new
MethodValidationPostProcessor
();
}
}
interface
InterfaceWithConstraint
{
void
call
(
@Min
(
42
)
Integer
counter
);
}
@Validated
static
class
ImplementationOfInterfaceWithConstraint
implements
InterfaceWithConstraint
{
@Override
public
void
call
(
Integer
counter
)
{
}
}
}
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAnnotationAutoConfigurationTests.java
View file @
81fef71f
This diff is collapsed.
Click to expand it.
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfigurationTests.java
View file @
81fef71f
This diff is collapsed.
Click to expand it.
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerDirectMockMvcTests.java
View file @
81fef71f
...
...
@@ -36,6 +36,7 @@ import org.junit.rules.ExpectedException;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
;
import
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
;
import
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
;
...
...
@@ -129,9 +130,9 @@ public class BasicErrorControllerDirectMockMvcTests {
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Documented
@Import
({
ServletWebServerFactoryAutoConfiguration
.
class
,
DispatcherServletAutoConfiguration
.
class
,
WebMvc
AutoConfiguration
.
class
,
HttpMessageConvertersAutoConfiguration
.
class
,
ErrorMvc
AutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
DispatcherServletAutoConfiguration
.
class
,
Validation
AutoConfiguration
.
class
,
WebMvcAutoConfiguration
.
class
,
HttpMessageConverters
AutoConfiguration
.
class
,
ErrorMvcAutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
protected
@interface
MinimalWebConfiguration
{
}
...
...
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorControllerMockMvcTests.java
View file @
81fef71f
...
...
@@ -36,6 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
;
import
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration
;
import
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
;
import
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
;
...
...
@@ -131,9 +132,9 @@ public class BasicErrorControllerMockMvcTests {
@Documented
@Import
({
ServletWebServerFactoryAutoConfiguration
.
EmbeddedTomcat
.
class
,
ServletWebServerFactoryAutoConfiguration
.
class
,
DispatcherServletAutoConfiguration
.
class
,
WebMvc
AutoConfiguration
.
class
,
HttpMessageConvertersAutoConfiguration
.
class
,
ErrorMvc
AutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
DispatcherServletAutoConfiguration
.
class
,
Validation
AutoConfiguration
.
class
,
WebMvcAutoConfiguration
.
class
,
HttpMessageConverters
AutoConfiguration
.
class
,
ErrorMvcAutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
})
private
@interface
MinimalWebConfiguration
{
}
...
...
spring-boot-cli/src/main/java/org/springframework/boot/cli/command/options/OptionSetGroovyCompilerConfiguration.java
View file @
81fef71f
...
...
@@ -92,4 +92,9 @@ public class OptionSetGroovyCompilerConfiguration implements GroovyCompilerConfi
return
this
.
repositoryConfiguration
;
}
@Override
public
boolean
isQuiet
()
{
return
false
;
}
}
spring-boot-cli/src/main/java/org/springframework/boot/cli/command/run/RunCommand.java
View file @
81fef71f
...
...
@@ -140,7 +140,7 @@ public class RunCommand extends OptionParsingCommand {
@Override
public
Level
getLogLevel
()
{
if
(
getOptions
().
has
(
RunOptionHandler
.
this
.
quietOption
))
{
if
(
isQuiet
(
))
{
return
Level
.
OFF
;
}
if
(
getOptions
().
has
(
RunOptionHandler
.
this
.
verboseOption
))
{
...
...
@@ -149,6 +149,11 @@ public class RunCommand extends OptionParsingCommand {
return
Level
.
INFO
;
}
@Override
public
boolean
isQuiet
()
{
return
getOptions
().
has
(
RunOptionHandler
.
this
.
quietOption
);
}
}
}
...
...
spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompiler.java
View file @
81fef71f
...
...
@@ -95,7 +95,8 @@ public class GroovyCompiler {
new
SpringBootDependenciesDependencyManagement
());
AetherGrapeEngine
grapeEngine
=
AetherGrapeEngineFactory
.
create
(
this
.
loader
,
configuration
.
getRepositoryConfiguration
(),
resolutionContext
);
configuration
.
getRepositoryConfiguration
(),
resolutionContext
,
configuration
.
isQuiet
());
GrapeEngineInstaller
.
install
(
grapeEngine
);
...
...
spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/GroovyCompilerConfiguration.java
View file @
81fef71f
...
...
@@ -71,4 +71,10 @@ public interface GroovyCompilerConfiguration {
*/
List
<
RepositoryConfiguration
>
getRepositoryConfiguration
();
/**
* Returns if running in quiet mode.
* @return {@code true} if running in quiet mode
*/
boolean
isQuiet
();
}
spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/AetherGrapeEngine.java
View file @
81fef71f
...
...
@@ -77,7 +77,7 @@ public class AetherGrapeEngine implements GrapeEngine {
RepositorySystem
repositorySystem
,
DefaultRepositorySystemSession
repositorySystemSession
,
List
<
RemoteRepository
>
remoteRepositories
,
DependencyResolutionContext
resolutionContext
)
{
DependencyResolutionContext
resolutionContext
,
boolean
quiet
)
{
this
.
classLoader
=
classLoader
;
this
.
repositorySystem
=
repositorySystem
;
this
.
session
=
repositorySystemSession
;
...
...
@@ -88,12 +88,14 @@ public class AetherGrapeEngine implements GrapeEngine {
for
(
RemoteRepository
repository
:
remotes
)
{
addRepository
(
repository
);
}
this
.
progressReporter
=
getProgressReporter
(
this
.
session
);
this
.
progressReporter
=
getProgressReporter
(
this
.
session
,
quiet
);
}
private
ProgressReporter
getProgressReporter
(
DefaultRepositorySystemSession
session
)
{
String
progressReporter
=
System
.
getProperty
(
"org.springframework.boot.cli.compiler.grape.ProgressReporter"
);
private
ProgressReporter
getProgressReporter
(
DefaultRepositorySystemSession
session
,
boolean
quiet
)
{
String
progressReporter
=
(
quiet
?
"none"
:
System
.
getProperty
(
"org.springframework.boot.cli.compiler.grape.ProgressReporter"
));
if
(
"detail"
.
equals
(
progressReporter
)
||
Boolean
.
getBoolean
(
"groovy.grape.report.downloads"
))
{
return
new
DetailedProgressReporter
(
session
,
System
.
out
);
...
...
spring-boot-cli/src/main/java/org/springframework/boot/cli/compiler/grape/AetherGrapeEngineFactory.java
View file @
81fef71f
...
...
@@ -44,27 +44,21 @@ public abstract class AetherGrapeEngineFactory {
public
static
AetherGrapeEngine
create
(
GroovyClassLoader
classLoader
,
List
<
RepositoryConfiguration
>
repositoryConfigurations
,
DependencyResolutionContext
dependencyResolutionContext
)
{
DependencyResolutionContext
dependencyResolutionContext
,
boolean
quiet
)
{
RepositorySystem
repositorySystem
=
createServiceLocator
()
.
getService
(
RepositorySystem
.
class
);
DefaultRepositorySystemSession
repositorySystemSession
=
MavenRepositorySystemUtils
.
newSession
();
ServiceLoader
<
RepositorySystemSessionAutoConfiguration
>
autoConfigurations
=
ServiceLoader
.
load
(
RepositorySystemSessionAutoConfiguration
.
class
);
for
(
RepositorySystemSessionAutoConfiguration
autoConfiguration
:
autoConfigurations
)
{
autoConfiguration
.
apply
(
repositorySystemSession
,
repositorySystem
);
}
new
DefaultRepositorySystemSessionAutoConfiguration
()
.
apply
(
repositorySystemSession
,
repositorySystem
);
return
new
AetherGrapeEngine
(
classLoader
,
repositorySystem
,
repositorySystemSession
,
createRepositories
(
repositoryConfigurations
),
dependencyResolutionContext
);
dependencyResolutionContext
,
quiet
);
}
private
static
ServiceLocator
createServiceLocator
()
{
...
...
spring-boot-cli/src/test/java/org/springframework/boot/cli/command/install/GroovyGrabDependencyResolverTests.java
View file @
81fef71f
...
...
@@ -81,6 +81,11 @@ public class GroovyGrabDependencyResolverTests {
return
new
String
[]
{
"."
};
}
@Override
public
boolean
isQuiet
()
{
return
false
;
}
};
this
.
resolver
=
new
GroovyGrabDependencyResolver
(
configuration
);
}
...
...
spring-boot-cli/src/test/java/org/springframework/boot/cli/compiler/grape/AetherGrapeEngineTests.java
View file @
81fef71f
...
...
@@ -59,7 +59,7 @@ public class AetherGrapeEngineTests {
dependencyResolutionContext
.
addDependencyManagement
(
new
SpringBootDependenciesDependencyManagement
());
return
AetherGrapeEngineFactory
.
create
(
this
.
groovyClassLoader
,
repositoryConfigurations
,
dependencyResolutionContext
);
repositoryConfigurations
,
dependencyResolutionContext
,
false
);
}
@Test
...
...
spring-boot-docs/src/main/asciidoc/appendix-executable-jar-format.adoc
View file @
81fef71f
...
...
@@ -283,6 +283,8 @@ the `Main-Class` attribute and leave out `Start-Class`.
* `loader.path` can contain directories (scanned recursively for jar and zip files),
archive paths, a directory within an archive that is scanned for jar files (for
example, `dependencies.jar!/lib`), or wildcard patterns (for the default JVM behavior).
Archive paths can be relative to `loader.home`, or anywhere in the file system with a
`jar:file:` prefix.
* `loader.path` (if empty) defaults to `BOOT-INF/lib` (meaning a local directory or a
nested one if running from an archive). Because of this `PropertiesLauncher` behaves the
same as `JarLauncher` when no additional configuration is provided.
...
...
spring-boot-test/src/main/java/org/springframework/boot/test/context/SpringBootTestContextBootstrapper.java
View file @
81fef71f
...
...
@@ -250,8 +250,7 @@ public class SpringBootTestContextBootstrapper extends DefaultTestContextBootstr
protected
Class
<?>[]
getOrFindConfigurationClasses
(
MergedContextConfiguration
mergedConfig
)
{
Class
<?>[]
classes
=
mergedConfig
.
getClasses
();
if
(
containsNonTestComponent
(
classes
)
||
mergedConfig
.
hasLocations
()
||
!
mergedConfig
.
getContextInitializerClasses
().
isEmpty
())
{
if
(
containsNonTestComponent
(
classes
)
||
mergedConfig
.
hasLocations
())
{
return
classes
;
}
Class
<?>
found
=
new
SpringBootConfigurationFinder
()
...
...
spring-boot-test/src/test/java/org/springframework/boot/test/context/bootstrap/SpringBootTestContextBootstrapperWithInitializersTests.java
0 → 100644
View file @
81fef71f
/*
* Copyright 2012-2016 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
.
test
.
context
.
bootstrap
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTestContextBootstrapper
;
import
org.springframework.boot.test.context.bootstrap.SpringBootTestContextBootstrapperWithInitializersTests.CustomInitializer
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextInitializer
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.test.context.BootstrapWith
;
import
org.springframework.test.context.ContextConfiguration
;
import
org.springframework.test.context.junit4.SpringRunner
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Integration tests for {@link SpringBootTestContextBootstrapper} with and
* {@link ApplicationContextInitializer}.
*
* @author Phillip Webb
*/
@RunWith
(
SpringRunner
.
class
)
@BootstrapWith
(
SpringBootTestContextBootstrapper
.
class
)
@ContextConfiguration
(
initializers
=
CustomInitializer
.
class
)
public
class
SpringBootTestContextBootstrapperWithInitializersTests
{
@Autowired
private
ApplicationContext
context
;
@Test
public
void
foundConfiguration
()
throws
Exception
{
Object
bean
=
this
.
context
.
getBean
(
SpringBootTestContextBootstrapperExampleConfig
.
class
);
assertThat
(
bean
).
isNotNull
();
}
// gh-8483
public
static
class
CustomInitializer
implements
ApplicationContextInitializer
<
ConfigurableApplicationContext
>
{
@Override
public
void
initialize
(
ConfigurableApplicationContext
applicationContext
)
{
}
}
}
spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/PropertiesLauncher.java
View file @
81fef71f
...
...
@@ -25,8 +25,10 @@ import java.net.URL;
import
java.net.URLConnection
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.LinkedHashSet
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.Set
;
import
java.util.jar.Manifest
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
...
...
@@ -299,11 +301,9 @@ public class PropertiesLauncher extends Launcher {
List
<
String
>
paths
=
new
ArrayList
<>();
for
(
String
path
:
commaSeparatedPaths
.
split
(
","
))
{
path
=
cleanupPath
(
path
);
// Empty path (i.e. the archive itself if running from a JAR) is always added
// to the classpath so no need for it to be explicitly listed
if
(!
path
.
equals
(
""
))
{
paths
.
add
(
path
);
}
// "" means the user wants root of archive but not current directory
path
=
(
""
.
equals
(
path
)
?
"/"
:
path
);
paths
.
add
(
path
);
}
if
(
paths
.
isEmpty
())
{
paths
.
add
(
"lib"
);
...
...
@@ -336,7 +336,13 @@ public class PropertiesLauncher extends Launcher {
@Override
protected
ClassLoader
createClassLoader
(
List
<
Archive
>
archives
)
throws
Exception
{
ClassLoader
loader
=
super
.
createClassLoader
(
archives
);
Set
<
URL
>
urls
=
new
LinkedHashSet
<
URL
>(
archives
.
size
());
for
(
Archive
archive
:
archives
)
{
urls
.
add
(
archive
.
getUrl
());
}
ClassLoader
loader
=
new
LaunchedURLClassLoader
(
urls
.
toArray
(
new
URL
[
0
]),
getClass
().
getClassLoader
());
debug
(
"Classpath: "
+
urls
);
String
customLoaderClassName
=
getProperty
(
"loader.classLoader"
);
if
(
customLoaderClassName
!=
null
)
{
loader
=
wrapWithCustomClassLoader
(
loader
,
customLoaderClassName
);
...
...
@@ -454,13 +460,15 @@ public class PropertiesLauncher extends Launcher {
String
root
=
cleanupPath
(
stripFileUrlPrefix
(
path
));
List
<
Archive
>
lib
=
new
ArrayList
<>();
File
file
=
new
File
(
root
);
if
(!
isAbsolutePath
(
root
))
{
file
=
new
File
(
this
.
home
,
root
);
}
if
(
file
.
isDirectory
())
{
debug
(
"Adding classpath entries from "
+
file
);
Archive
archive
=
new
ExplodedArchive
(
file
,
false
);
lib
.
add
(
archive
);
if
(!
"/"
.
equals
(
root
))
{
if
(!
isAbsolutePath
(
root
))
{
file
=
new
File
(
this
.
home
,
root
);
}
if
(
file
.
isDirectory
())
{
debug
(
"Adding classpath entries from "
+
file
);
Archive
archive
=
new
ExplodedArchive
(
file
,
false
);
lib
.
add
(
archive
);
}
}
Archive
archive
=
getArchive
(
file
);
if
(
archive
!=
null
)
{
...
...
@@ -488,24 +496,46 @@ public class PropertiesLauncher extends Launcher {
return
null
;
}
private
List
<
Archive
>
getNestedArchives
(
String
root
)
throws
Exception
{
if
(
root
.
startsWith
(
"/"
)
||
this
.
parent
.
getUrl
().
equals
(
this
.
home
.
toURI
().
toURL
()))
{
private
List
<
Archive
>
getNestedArchives
(
String
path
)
throws
Exception
{
Archive
parent
=
this
.
parent
;
String
root
=
path
;
if
(!
root
.
equals
(
"/"
)
&&
root
.
startsWith
(
"/"
)
||
parent
.
getUrl
().
equals
(
this
.
home
.
toURI
().
toURL
()))
{
// If home dir is same as parent archive, no need to add it twice.
return
null
;
}
Archive
parent
=
this
.
parent
;
if
(
root
.
startsWith
(
"jar:file:"
)
&&
root
.
contains
(
"!"
))
{
if
(
root
.
contains
(
"!"
))
{
int
index
=
root
.
indexOf
(
"!"
);
String
file
=
root
.
substring
(
"jar:file:"
.
length
(),
index
);
parent
=
new
JarFileArchive
(
new
File
(
file
));
File
file
=
new
File
(
this
.
home
,
root
.
substring
(
0
,
index
));
if
(
root
.
startsWith
(
"jar:file:"
))
{
file
=
new
File
(
root
.
substring
(
"jar:file:"
.
length
(),
index
));
}
parent
=
new
JarFileArchive
(
file
);
root
=
root
.
substring
(
index
+
1
,
root
.
length
());
while
(
root
.
startsWith
(
"/"
))
{
root
=
root
.
substring
(
1
);
}
}
if
(
root
.
endsWith
(
".jar"
))
{
File
file
=
new
File
(
this
.
home
,
root
);
if
(
file
.
exists
())
{
parent
=
new
JarFileArchive
(
file
);
root
=
""
;
}
}
if
(
root
.
equals
(
"/"
)
||
root
.
equals
(
"./"
)
||
root
.
equals
(
"."
))
{
// The prefix for nested jars is actually empty if it's at the root
root
=
""
;
}
EntryFilter
filter
=
new
PrefixMatchingArchiveFilter
(
root
);
return
parent
.
getNestedArchives
(
filter
);
List
<
Archive
>
archives
=
new
ArrayList
<
Archive
>(
parent
.
getNestedArchives
(
filter
));
if
((
""
.
equals
(
root
)
||
"."
.
equals
(
root
))
&&
!
path
.
endsWith
(
".jar"
)
&&
parent
!=
this
.
parent
)
{
// You can't find the root with an entry filter so it has to be added
// explicitly. But don't add the root of the parent archive.
archives
.
add
(
parent
);
}
return
archives
;
}
private
void
addNestedEntries
(
List
<
Archive
>
lib
)
{
...
...
@@ -518,7 +548,7 @@ public class PropertiesLauncher extends Launcher {
@Override
public
boolean
matches
(
Entry
entry
)
{
if
(
entry
.
isDirectory
())
{
return
entry
.
getName
().
startsWith
(
JarLauncher
.
BOOT_INF_CLASSES
);
return
entry
.
getName
().
equals
(
JarLauncher
.
BOOT_INF_CLASSES
);
}
return
entry
.
getName
().
startsWith
(
JarLauncher
.
BOOT_INF_LIB
);
}
...
...
@@ -607,6 +637,9 @@ public class PropertiesLauncher extends Launcher {
@Override
public
boolean
matches
(
Entry
entry
)
{
if
(
entry
.
isDirectory
())
{
return
entry
.
getName
().
equals
(
this
.
prefix
);
}
return
entry
.
getName
().
startsWith
(
this
.
prefix
)
&&
this
.
filter
.
matches
(
entry
);
}
...
...
spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/PropertiesLauncherTests.java
View file @
81fef71f
...
...
@@ -21,12 +21,13 @@ import java.io.FileOutputStream;
import
java.io.IOException
;
import
java.net.URL
;
import
java.net.URLClassLoader
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.jar.Attributes
;
import
java.util.jar.Manifest
;
import
org.assertj.core.api.Condition
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Rule
;
...
...
@@ -36,6 +37,9 @@ import org.junit.rules.TemporaryFolder;
import
org.mockito.MockitoAnnotations
;
import
org.springframework.boot.loader.archive.Archive
;
import
org.springframework.boot.loader.archive.ExplodedArchive
;
import
org.springframework.boot.loader.archive.JarFileArchive
;
import
org.springframework.core.io.FileSystemResource
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
...
...
@@ -72,6 +76,7 @@ public class PropertiesLauncherTests {
System
.
clearProperty
(
"loader.config.name"
);
System
.
clearProperty
(
"loader.config.location"
);
System
.
clearProperty
(
"loader.system"
);
System
.
clearProperty
(
"loader.classLoader"
);
}
@Test
...
...
@@ -131,6 +136,16 @@ public class PropertiesLauncherTests {
.
isEqualTo
(
"[.]"
);
}
@Test
public
void
testUserSpecifiedSlashPath
()
throws
Exception
{
System
.
setProperty
(
"loader.path"
,
"jars/"
);
PropertiesLauncher
launcher
=
new
PropertiesLauncher
();
assertThat
(
ReflectionTestUtils
.
getField
(
launcher
,
"paths"
).
toString
())
.
isEqualTo
(
"[jars/]"
);
List
<
Archive
>
archives
=
launcher
.
getClassPathArchives
();
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"app.jar!/"
));
}
@Test
public
void
testUserSpecifiedWildcardPath
()
throws
Exception
{
System
.
setProperty
(
"loader.path"
,
"jars/*"
);
...
...
@@ -153,13 +168,44 @@ public class PropertiesLauncherTests {
waitFor
(
"Hello World"
);
}
@Test
public
void
testUserSpecifiedRootOfJarPath
()
throws
Exception
{
System
.
setProperty
(
"loader.path"
,
"jar:file:./src/test/resources/nested-jars/app.jar!/"
);
PropertiesLauncher
launcher
=
new
PropertiesLauncher
();
assertThat
(
ReflectionTestUtils
.
getField
(
launcher
,
"paths"
).
toString
())
.
isEqualTo
(
"[jar:file:./src/test/resources/nested-jars/app.jar!/]"
);
List
<
Archive
>
archives
=
launcher
.
getClassPathArchives
();
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"foo.jar!/"
));
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"app.jar!/"
));
}
@Test
public
void
testUserSpecifiedRootOfJarPathWithDot
()
throws
Exception
{
System
.
setProperty
(
"loader.path"
,
"nested-jars/app.jar!/./"
);
PropertiesLauncher
launcher
=
new
PropertiesLauncher
();
List
<
Archive
>
archives
=
launcher
.
getClassPathArchives
();
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"foo.jar!/"
));
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"app.jar!/"
));
}
@Test
public
void
testUserSpecifiedRootOfJarPathWithDotAndJarPrefix
()
throws
Exception
{
System
.
setProperty
(
"loader.path"
,
"jar:file:./src/test/resources/nested-jars/app.jar!/./"
);
PropertiesLauncher
launcher
=
new
PropertiesLauncher
();
List
<
Archive
>
archives
=
launcher
.
getClassPathArchives
();
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"foo.jar!/"
));
}
@Test
public
void
testUserSpecifiedJarFileWithNestedArchives
()
throws
Exception
{
System
.
setProperty
(
"loader.path"
,
"nested-jars/app.jar"
);
System
.
setProperty
(
"loader.main"
,
"demo.Application"
);
PropertiesLauncher
launcher
=
new
PropertiesLauncher
();
launcher
.
launch
(
new
String
[
0
]);
waitFor
(
"Hello World"
);
List
<
Archive
>
archives
=
launcher
.
getClassPathArchives
();
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"foo.jar!/"
));
assertThat
(
archives
).
areExactly
(
1
,
endingWith
(
"app.jar!/"
));
}
@Test
...
...
@@ -209,11 +255,28 @@ public class PropertiesLauncherTests {
public
void
testCustomClassLoaderCreation
()
throws
Exception
{
System
.
setProperty
(
"loader.classLoader"
,
TestLoader
.
class
.
getName
());
PropertiesLauncher
launcher
=
new
PropertiesLauncher
();
ClassLoader
loader
=
launcher
.
createClassLoader
(
Collections
.<
Archive
>
emptyList
());
ClassLoader
loader
=
launcher
.
createClassLoader
(
archives
());
assertThat
(
loader
).
isNotNull
();
assertThat
(
loader
.
getClass
().
getName
()).
isEqualTo
(
TestLoader
.
class
.
getName
());
}
private
List
<
Archive
>
archives
()
throws
Exception
{
List
<
Archive
>
archives
=
new
ArrayList
<
Archive
>();
String
path
=
System
.
getProperty
(
"java.class.path"
);
for
(
String
url
:
path
.
split
(
File
.
pathSeparator
))
{
archives
.
add
(
archive
(
url
));
}
return
archives
;
}
private
Archive
archive
(
String
url
)
throws
IOException
{
File
file
=
new
FileSystemResource
(
url
).
getFile
();
if
(
url
.
endsWith
(
".jar"
))
{
return
new
JarFileArchive
(
file
);
}
return
new
ExplodedArchive
(
file
);
}
@Test
public
void
testUserSpecifiedConfigPathWins
()
throws
Exception
{
...
...
@@ -280,6 +343,17 @@ public class PropertiesLauncherTests {
assertThat
(
timeout
).
as
(
"Timed out waiting for ("
+
value
+
")"
).
isTrue
();
}
private
Condition
<
Archive
>
endingWith
(
final
String
value
)
{
return
new
Condition
<
Archive
>()
{
@Override
public
boolean
matches
(
Archive
archive
)
{
return
archive
.
toString
().
endsWith
(
value
);
}
};
}
public
static
class
TestLoader
extends
URLClassLoader
{
public
TestLoader
(
ClassLoader
parent
)
{
...
...
spring-boot-tools/spring-boot-loader/src/test/resources/nested-jars/app.jar
View file @
81fef71f
No preview for this file type
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