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
3c203e9b
Commit
3c203e9b
authored
Apr 06, 2019
by
Madhura Bhave
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update devtools to use @Lazy(false)
Fixes gh-16184
parent
ce028240
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
223 additions
and
67 deletions
+223
-67
EagerInitializationAutoConfiguration.java
...s/autoconfigure/EagerInitializationAutoConfiguration.java
+0
-66
LocalDevToolsAutoConfiguration.java
...evtools/autoconfigure/LocalDevToolsAutoConfiguration.java
+2
-0
spring.factories
...oot-devtools/src/main/resources/META-INF/spring.factories
+0
-1
ApplicationLauncher.java
...ingframework/boot/devtools/tests/ApplicationLauncher.java
+4
-0
DevToolsWithLazyInitializationIntegrationTests.java
...tests/DevToolsWithLazyInitializationIntegrationTests.java
+183
-0
LocalApplicationLauncher.java
...amework/boot/devtools/tests/LocalApplicationLauncher.java
+15
-0
RemoteApplicationLauncher.java
...mework/boot/devtools/tests/RemoteApplicationLauncher.java
+19
-0
No files found.
spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/EagerInitializationAutoConfiguration.java
deleted
100644 → 0
View file @
ce028240
/*
* Copyright 2012-2019 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
*
* https://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
.
devtools
.
autoconfigure
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.BeanFactoryPostProcessor
;
import
org.springframework.beans.factory.config.ConfigurableListableBeanFactory
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.Ordered
;
/**
* {@link EnableAutoConfiguration Auto-configuration} to ensure that DevTools' beans are
* eagerly initialized when the application is otherwise being initialized lazily.
*
* @author Andy Wilkinson
* @since 2.2.0
*/
@Configuration
(
proxyBeanMethods
=
false
)
public
class
EagerInitializationAutoConfiguration
{
@Bean
public
static
AlwaysEagerBeanFactoryPostProcessor
alwaysEagerBeanFactoryPostProcessor
()
{
return
new
AlwaysEagerBeanFactoryPostProcessor
();
}
private
static
final
class
AlwaysEagerBeanFactoryPostProcessor
implements
BeanFactoryPostProcessor
,
Ordered
{
@Override
public
void
postProcessBeanFactory
(
ConfigurableListableBeanFactory
beanFactory
)
throws
BeansException
{
for
(
String
name
:
beanFactory
.
getBeanDefinitionNames
())
{
BeanDefinition
beanDefinition
=
beanFactory
.
getBeanDefinition
(
name
);
String
factoryBeanName
=
beanDefinition
.
getFactoryBeanName
();
if
(
factoryBeanName
!=
null
&&
factoryBeanName
.
startsWith
(
"org.springframework.boot.devtools"
))
{
beanDefinition
.
setLazyInit
(
false
);
}
}
}
@Override
public
int
getOrder
()
{
return
Ordered
.
HIGHEST_PRECEDENCE
+
1
;
}
}
}
spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/autoconfigure/LocalDevToolsAutoConfiguration.java
View file @
3c203e9b
...
@@ -39,6 +39,7 @@ import org.springframework.context.ApplicationEvent;
...
@@ -39,6 +39,7 @@ import org.springframework.context.ApplicationEvent;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.context.event.ContextRefreshedEvent
;
import
org.springframework.context.event.ContextRefreshedEvent
;
import
org.springframework.context.event.GenericApplicationListener
;
import
org.springframework.context.event.GenericApplicationListener
;
import
org.springframework.core.ResolvableType
;
import
org.springframework.core.ResolvableType
;
...
@@ -90,6 +91,7 @@ public class LocalDevToolsAutoConfiguration {
...
@@ -90,6 +91,7 @@ public class LocalDevToolsAutoConfiguration {
/**
/**
* Local Restart Configuration.
* Local Restart Configuration.
*/
*/
@Lazy
(
false
)
@Configuration
(
proxyBeanMethods
=
false
)
@Configuration
(
proxyBeanMethods
=
false
)
@ConditionalOnProperty
(
prefix
=
"spring.devtools.restart"
,
name
=
"enabled"
,
@ConditionalOnProperty
(
prefix
=
"spring.devtools.restart"
,
name
=
"enabled"
,
matchIfMissing
=
true
)
matchIfMissing
=
true
)
...
...
spring-boot-project/spring-boot-devtools/src/main/resources/META-INF/spring.factories
View file @
3c203e9b
...
@@ -9,7 +9,6 @@ org.springframework.boot.devtools.logger.DevToolsLogFactory.Listener
...
@@ -9,7 +9,6 @@ org.springframework.boot.devtools.logger.DevToolsLogFactory.Listener
# Auto Configure
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.devtools.autoconfigure.EagerInitializationAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.DevToolsDataSourceAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.LocalDevToolsAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.LocalDevToolsAutoConfiguration,\
org.springframework.boot.devtools.autoconfigure.RemoteDevToolsAutoConfiguration
org.springframework.boot.devtools.autoconfigure.RemoteDevToolsAutoConfiguration
...
...
spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/ApplicationLauncher.java
View file @
3c203e9b
...
@@ -22,10 +22,14 @@ import java.io.File;
...
@@ -22,10 +22,14 @@ import java.io.File;
* Launches an application with DevTools.
* Launches an application with DevTools.
*
*
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author Madhura Bhave
*/
*/
public
interface
ApplicationLauncher
{
public
interface
ApplicationLauncher
{
LaunchedApplication
launchApplication
(
JvmLauncher
javaLauncher
,
File
serverPortFile
)
LaunchedApplication
launchApplication
(
JvmLauncher
javaLauncher
,
File
serverPortFile
)
throws
Exception
;
throws
Exception
;
LaunchedApplication
launchApplication
(
JvmLauncher
jvmLauncher
,
File
serverPortFile
,
String
...
additionalArgs
)
throws
Exception
;
}
}
spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/DevToolsWithLazyInitializationIntegrationTests.java
0 → 100644
View file @
3c203e9b
/*
* Copyright 2012-2019 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
*
* https://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
.
devtools
.
tests
;
import
java.io.File
;
import
java.io.FileReader
;
import
java.io.IOException
;
import
java.time.Duration
;
import
java.util.ArrayList
;
import
java.util.List
;
import
net.bytebuddy.ByteBuddy
;
import
net.bytebuddy.description.annotation.AnnotationDescription
;
import
net.bytebuddy.description.modifier.Visibility
;
import
net.bytebuddy.dynamic.DynamicType
;
import
net.bytebuddy.implementation.FixedValue
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.ClassRule
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.TemporaryFolder
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.Parameterized
;
import
org.springframework.boot.test.web.client.TestRestTemplate
;
import
org.springframework.boot.testsupport.BuildOutput
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.util.FileCopyUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Integration tests for DevTools with lazy initialization enabled.
*
* @author Madhura Bhave
*/
@RunWith
(
Parameterized
.
class
)
public
class
DevToolsWithLazyInitializationIntegrationTests
{
@ClassRule
public
static
final
TemporaryFolder
temp
=
new
TemporaryFolder
();
private
static
final
BuildOutput
buildOutput
=
new
BuildOutput
(
DevToolsIntegrationTests
.
class
);
private
LaunchedApplication
launchedApplication
;
private
final
File
serverPortFile
;
private
final
ApplicationLauncher
applicationLauncher
;
private
String
[]
args
;
@Rule
public
JvmLauncher
javaLauncher
=
new
JvmLauncher
();
public
DevToolsWithLazyInitializationIntegrationTests
(
ApplicationLauncher
applicationLauncher
)
{
this
.
applicationLauncher
=
applicationLauncher
;
this
.
serverPortFile
=
new
File
(
buildOutput
.
getRootLocation
(),
"server.port"
);
}
@Before
public
void
launchApplication
()
throws
Exception
{
this
.
serverPortFile
.
delete
();
this
.
launchedApplication
=
this
.
applicationLauncher
.
launchApplication
(
this
.
javaLauncher
,
this
.
serverPortFile
,
"--spring.main.lazy-initialization=true"
);
}
@After
public
void
stopApplication
()
throws
InterruptedException
{
this
.
launchedApplication
.
stop
();
}
@Test
public
void
addARequestMappingToAnExistingControllerWhenLazyInit
()
throws
Exception
{
TestRestTemplate
template
=
new
TestRestTemplate
();
String
urlBase
=
"http://localhost:"
+
awaitServerPort
();
assertThat
(
template
.
getForObject
(
urlBase
+
"/one"
,
String
.
class
))
.
isEqualTo
(
"one"
);
assertThat
(
template
.
getForEntity
(
urlBase
+
"/two"
,
String
.
class
).
getStatusCode
())
.
isEqualTo
(
HttpStatus
.
NOT_FOUND
);
controller
(
"com.example.ControllerOne"
).
withRequestMapping
(
"one"
)
.
withRequestMapping
(
"two"
).
build
();
urlBase
=
"http://localhost:"
+
awaitServerPort
();
assertThat
(
template
.
getForObject
(
urlBase
+
"/one"
,
String
.
class
))
.
isEqualTo
(
"one"
);
assertThat
(
template
.
getForObject
(
urlBase
+
"/two"
,
String
.
class
))
.
isEqualTo
(
"two"
);
}
private
int
awaitServerPort
()
throws
Exception
{
Duration
timeToWait
=
Duration
.
ofSeconds
(
40
);
long
end
=
System
.
currentTimeMillis
()
+
timeToWait
.
toMillis
();
System
.
out
.
println
(
"Reading server port from '"
+
this
.
serverPortFile
+
"'"
);
while
(
this
.
serverPortFile
.
length
()
==
0
)
{
if
(
System
.
currentTimeMillis
()
>
end
)
{
throw
new
IllegalStateException
(
String
.
format
(
"server.port file '"
+
this
.
serverPortFile
+
"' was not written within "
+
timeToWait
.
toMillis
()
+
"ms. "
+
"Application output:%n%s%s"
,
FileCopyUtils
.
copyToString
(
new
FileReader
(
this
.
launchedApplication
.
getStandardOut
())),
FileCopyUtils
.
copyToString
(
new
FileReader
(
this
.
launchedApplication
.
getStandardError
()))));
}
Thread
.
sleep
(
100
);
}
FileReader
portReader
=
new
FileReader
(
this
.
serverPortFile
);
int
port
=
Integer
.
valueOf
(
FileCopyUtils
.
copyToString
(
portReader
));
this
.
serverPortFile
.
delete
();
System
.
out
.
println
(
"Got port "
+
port
);
this
.
launchedApplication
.
restartRemote
(
port
);
Thread
.
sleep
(
1000
);
return
port
;
}
private
ControllerBuilder
controller
(
String
name
)
{
return
new
ControllerBuilder
(
name
,
this
.
launchedApplication
.
getClassesDirectory
());
}
@Parameterized
.
Parameters
(
name
=
"{0}"
)
public
static
Object
[]
parameters
()
throws
IOException
{
Directories
directories
=
new
Directories
(
buildOutput
,
temp
);
return
new
Object
[]
{
new
Object
[]
{
new
LocalApplicationLauncher
(
directories
)
},
new
Object
[]
{
new
ExplodedRemoteApplicationLauncher
(
directories
)
},
new
Object
[]
{
new
JarFileRemoteApplicationLauncher
(
directories
)
}
};
}
private
static
final
class
ControllerBuilder
{
private
final
List
<
String
>
mappings
=
new
ArrayList
<>();
private
final
String
name
;
private
final
File
classesDirectory
;
private
ControllerBuilder
(
String
name
,
File
classesDirectory
)
{
this
.
name
=
name
;
this
.
classesDirectory
=
classesDirectory
;
}
public
ControllerBuilder
withRequestMapping
(
String
mapping
)
{
this
.
mappings
.
add
(
mapping
);
return
this
;
}
public
void
build
()
throws
Exception
{
DynamicType
.
Builder
<
Object
>
builder
=
new
ByteBuddy
().
subclass
(
Object
.
class
)
.
name
(
this
.
name
).
annotateType
(
AnnotationDescription
.
Builder
.
ofType
(
RestController
.
class
).
build
());
for
(
String
mapping
:
this
.
mappings
)
{
builder
=
builder
.
defineMethod
(
mapping
,
String
.
class
,
Visibility
.
PUBLIC
)
.
intercept
(
FixedValue
.
value
(
mapping
)).
annotateMethod
(
AnnotationDescription
.
Builder
.
ofType
(
RequestMapping
.
class
)
.
defineArray
(
"value"
,
mapping
).
build
());
}
builder
.
make
().
saveIn
(
this
.
classesDirectory
);
}
}
}
spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/LocalApplicationLauncher.java
View file @
3c203e9b
...
@@ -18,6 +18,7 @@ package org.springframework.boot.devtools.tests;
...
@@ -18,6 +18,7 @@ package org.springframework.boot.devtools.tests;
import
java.io.File
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
org.springframework.boot.devtools.tests.JvmLauncher.LaunchedJvm
;
import
org.springframework.boot.devtools.tests.JvmLauncher.LaunchedJvm
;
...
@@ -45,6 +46,20 @@ public class LocalApplicationLauncher extends AbstractApplicationLauncher {
...
@@ -45,6 +46,20 @@ public class LocalApplicationLauncher extends AbstractApplicationLauncher {
null
);
null
);
}
}
@Override
public
LaunchedApplication
launchApplication
(
JvmLauncher
jvmLauncher
,
File
serverPortFile
,
String
...
additionalArgs
)
throws
Exception
{
List
<
String
>
args
=
new
ArrayList
<>(
Arrays
.
asList
(
"com.example.DevToolsTestApplication"
,
serverPortFile
.
getAbsolutePath
(),
"--server.port=0"
));
args
.
addAll
(
Arrays
.
asList
(
additionalArgs
));
LaunchedJvm
jvm
=
jvmLauncher
.
launch
(
"local"
,
createApplicationClassPath
(),
args
.
toArray
(
new
String
[]
{}));
return
new
LaunchedApplication
(
getDirectories
().
getAppDirectory
(),
jvm
.
getStandardOut
(),
jvm
.
getStandardError
(),
jvm
.
getProcess
(),
null
,
null
);
}
protected
String
createApplicationClassPath
()
throws
Exception
{
protected
String
createApplicationClassPath
()
throws
Exception
{
File
appDirectory
=
getDirectories
().
getAppDirectory
();
File
appDirectory
=
getDirectories
().
getAppDirectory
();
copyApplicationTo
(
appDirectory
);
copyApplicationTo
(
appDirectory
);
...
...
spring-boot-tests/spring-boot-integration-tests/spring-boot-devtools-tests/src/test/java/org/springframework/boot/devtools/tests/RemoteApplicationLauncher.java
View file @
3c203e9b
...
@@ -19,6 +19,7 @@ package org.springframework.boot.devtools.tests;
...
@@ -19,6 +19,7 @@ package org.springframework.boot.devtools.tests;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileReader
;
import
java.io.FileReader
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
java.util.function.BiFunction
;
import
java.util.function.BiFunction
;
...
@@ -55,6 +56,24 @@ abstract class RemoteApplicationLauncher extends AbstractApplicationLauncher {
...
@@ -55,6 +56,24 @@ abstract class RemoteApplicationLauncher extends AbstractApplicationLauncher {
remoteRestarter
);
remoteRestarter
);
}
}
@Override
public
LaunchedApplication
launchApplication
(
JvmLauncher
javaLauncher
,
File
serverPortFile
,
String
...
additionalArgs
)
throws
Exception
{
List
<
String
>
args
=
new
ArrayList
<>(
Arrays
.
asList
(
"com.example.DevToolsTestApplication"
,
serverPortFile
.
getAbsolutePath
(),
"--server.port=0"
,
"--spring.devtools.remote.secret=secret"
));
args
.
addAll
(
Arrays
.
asList
(
additionalArgs
));
LaunchedJvm
applicationJvm
=
javaLauncher
.
launch
(
"app"
,
createApplicationClassPath
(),
args
.
toArray
(
new
String
[]
{}));
int
port
=
awaitServerPort
(
applicationJvm
.
getStandardOut
(),
serverPortFile
);
BiFunction
<
Integer
,
File
,
Process
>
remoteRestarter
=
getRemoteRestarter
(
javaLauncher
);
return
new
LaunchedApplication
(
getDirectories
().
getRemoteAppDirectory
(),
applicationJvm
.
getStandardOut
(),
applicationJvm
.
getStandardError
(),
applicationJvm
.
getProcess
(),
remoteRestarter
.
apply
(
port
,
null
),
remoteRestarter
);
}
private
BiFunction
<
Integer
,
File
,
Process
>
getRemoteRestarter
(
private
BiFunction
<
Integer
,
File
,
Process
>
getRemoteRestarter
(
JvmLauncher
javaLauncher
)
{
JvmLauncher
javaLauncher
)
{
return
(
port
,
classesDirectory
)
->
{
return
(
port
,
classesDirectory
)
->
{
...
...
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