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
531ee83c
Commit
531ee83c
authored
Apr 19, 2021
by
Stephane Nicoll
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.4.x'
Closes gh-26156
parents
177152e0
54613c77
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
191 additions
and
0 deletions
+191
-0
ScheduledBeanLazyInitializationExcludeFilter.java
...re/task/ScheduledBeanLazyInitializationExcludeFilter.java
+78
-0
TaskSchedulingAutoConfiguration.java
...t/autoconfigure/task/TaskSchedulingAutoConfiguration.java
+6
-0
ScheduledBeanLazyInitializationExcludeFilterTests.java
...sk/ScheduledBeanLazyInitializationExcludeFilterTests.java
+71
-0
TaskSchedulingAutoConfigurationTests.java
...oconfigure/task/TaskSchedulingAutoConfigurationTests.java
+36
-0
No files found.
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/ScheduledBeanLazyInitializationExcludeFilter.java
0 → 100644
View file @
531ee83c
/*
* Copyright 2012-2021 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
.
autoconfigure
.
task
;
import
java.lang.reflect.Method
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ScheduledExecutorService
;
import
org.springframework.aop.framework.AopInfrastructureBean
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.boot.LazyInitializationExcludeFilter
;
import
org.springframework.core.MethodIntrospector
;
import
org.springframework.core.annotation.AnnotatedElementUtils
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.scheduling.TaskScheduler
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.scheduling.annotation.Schedules
;
import
org.springframework.util.ClassUtils
;
/**
* A {@link LazyInitializationExcludeFilter} that detects bean methods annotated with
* {@link Scheduled} or {@link Schedules}.
*
* @author Stephane Nicoll
*/
class
ScheduledBeanLazyInitializationExcludeFilter
implements
LazyInitializationExcludeFilter
{
private
final
Set
<
Class
<?>>
nonAnnotatedClasses
=
Collections
.
newSetFromMap
(
new
ConcurrentHashMap
<>(
64
));
ScheduledBeanLazyInitializationExcludeFilter
()
{
// Ignore AOP infrastructure such as scoped proxies.
this
.
nonAnnotatedClasses
.
add
(
AopInfrastructureBean
.
class
);
this
.
nonAnnotatedClasses
.
add
(
TaskScheduler
.
class
);
this
.
nonAnnotatedClasses
.
add
(
ScheduledExecutorService
.
class
);
}
@Override
public
boolean
isExcluded
(
String
beanName
,
BeanDefinition
beanDefinition
,
Class
<?>
beanType
)
{
return
hasScheduledTask
(
beanType
);
}
private
boolean
hasScheduledTask
(
Class
<?>
type
)
{
Class
<?>
targetType
=
ClassUtils
.
getUserClass
(
type
);
if
(!
this
.
nonAnnotatedClasses
.
contains
(
targetType
)
&&
AnnotationUtils
.
isCandidateClass
(
targetType
,
Arrays
.
asList
(
Scheduled
.
class
,
Schedules
.
class
)))
{
Map
<
Method
,
Set
<
Scheduled
>>
annotatedMethods
=
MethodIntrospector
.
selectMethods
(
targetType
,
(
MethodIntrospector
.
MetadataLookup
<
Set
<
Scheduled
>>)
(
method
)
->
{
Set
<
Scheduled
>
scheduledAnnotations
=
AnnotatedElementUtils
.
getMergedRepeatableAnnotations
(
method
,
Scheduled
.
class
,
Schedules
.
class
);
return
(!
scheduledAnnotations
.
isEmpty
()
?
scheduledAnnotations
:
null
);
});
if
(
annotatedMethods
.
isEmpty
())
{
this
.
nonAnnotatedClasses
.
add
(
targetType
);
}
return
!
annotatedMethods
.
isEmpty
();
}
return
false
;
}
}
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.java
View file @
531ee83c
...
@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.task;
...
@@ -19,6 +19,7 @@ package org.springframework.boot.autoconfigure.task;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.ScheduledExecutorService
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.beans.factory.ObjectProvider
;
import
org.springframework.boot.LazyInitializationExcludeFilter
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.AutoConfigureAfter
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnBean
;
...
@@ -54,6 +55,11 @@ public class TaskSchedulingAutoConfiguration {
...
@@ -54,6 +55,11 @@ public class TaskSchedulingAutoConfiguration {
return
builder
.
build
();
return
builder
.
build
();
}
}
@Bean
public
static
LazyInitializationExcludeFilter
scheduledBeanLazyInitializationExcludeFilter
()
{
return
new
ScheduledBeanLazyInitializationExcludeFilter
();
}
@Bean
@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingBean
public
TaskSchedulerBuilder
taskSchedulerBuilder
(
TaskSchedulingProperties
properties
,
public
TaskSchedulerBuilder
taskSchedulerBuilder
(
TaskSchedulingProperties
properties
,
...
...
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/ScheduledBeanLazyInitializationExcludeFilterTests.java
0 → 100644
View file @
531ee83c
/*
* Copyright 2012-2021 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
.
autoconfigure
.
task
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.scheduling.annotation.Schedules
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
/**
* Tests for {@link ScheduledBeanLazyInitializationExcludeFilter}.
*
* @author Stephane Nicoll
*/
class
ScheduledBeanLazyInitializationExcludeFilterTests
{
private
final
ScheduledBeanLazyInitializationExcludeFilter
filter
=
new
ScheduledBeanLazyInitializationExcludeFilter
();
@Test
void
beanWithScheduledMethodIsDetected
()
{
assertThat
(
isExcluded
(
TestBean
.
class
)).
isTrue
();
}
@Test
void
beanWithSchedulesMethodIsDetected
()
{
assertThat
(
isExcluded
(
AnotherTestBean
.
class
)).
isTrue
();
}
@Test
void
beanWithoutScheduledMethodIsDetected
()
{
assertThat
(
isExcluded
(
ScheduledBeanLazyInitializationExcludeFilterTests
.
class
)).
isFalse
();
}
private
boolean
isExcluded
(
Class
<?>
type
)
{
return
this
.
filter
.
isExcluded
(
"test"
,
new
RootBeanDefinition
(
type
),
type
);
}
private
static
class
TestBean
{
@Scheduled
void
doStuff
()
{
}
}
private
static
class
AnotherTestBean
{
@Schedules
({
@Scheduled
(
fixedRate
=
5000
),
@Scheduled
(
fixedRate
=
2500
)
})
void
doStuff
()
{
}
}
}
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfigurationTests.java
View file @
531ee83c
...
@@ -16,6 +16,9 @@
...
@@ -16,6 +16,9 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
task
;
package
org
.
springframework
.
boot
.
autoconfigure
.
task
;
import
java.time.Duration
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.CountDownLatch
;
...
@@ -23,8 +26,10 @@ import java.util.concurrent.Executors;
...
@@ -23,8 +26,10 @@ import java.util.concurrent.Executors;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeUnit
;
import
org.awaitility.Awaitility
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
org.springframework.boot.LazyInitializationBeanFactoryPostProcessor
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.task.TaskSchedulerCustomizer
;
import
org.springframework.boot.task.TaskSchedulerCustomizer
;
import
org.springframework.boot.test.context.runner.ApplicationContextRunner
;
import
org.springframework.boot.test.context.runner.ApplicationContextRunner
;
...
@@ -121,6 +126,22 @@ class TaskSchedulingAutoConfigurationTests {
...
@@ -121,6 +126,22 @@ class TaskSchedulingAutoConfigurationTests {
});
});
}
}
@Test
void
enableSchedulingWithLazyInitializationInvokeScheduledMethods
()
{
List
<
String
>
threadNames
=
new
ArrayList
<>();
new
ApplicationContextRunner
()
.
withInitializer
((
context
)
->
context
.
addBeanFactoryPostProcessor
(
new
LazyInitializationBeanFactoryPostProcessor
()))
.
withPropertyValues
(
"spring.task.scheduling.thread-name-prefix=scheduling-test-"
)
.
withBean
(
LazyTestBean
.
class
,
()
->
new
LazyTestBean
(
threadNames
))
.
withUserConfiguration
(
SchedulingConfiguration
.
class
)
.
withConfiguration
(
AutoConfigurations
.
of
(
TaskSchedulingAutoConfiguration
.
class
)).
run
((
context
)
->
{
// No lazy lookup.
Awaitility
.
waitAtMost
(
Duration
.
ofSeconds
(
3
)).
until
(()
->
!
threadNames
.
isEmpty
());
assertThat
(
threadNames
).
allMatch
((
name
)
->
name
.
contains
(
"scheduling-test-"
));
});
}
@Configuration
(
proxyBeanMethods
=
false
)
@Configuration
(
proxyBeanMethods
=
false
)
@EnableScheduling
@EnableScheduling
static
class
SchedulingConfiguration
{
static
class
SchedulingConfiguration
{
...
@@ -193,6 +214,21 @@ class TaskSchedulingAutoConfigurationTests {
...
@@ -193,6 +214,21 @@ class TaskSchedulingAutoConfigurationTests {
}
}
static
class
LazyTestBean
{
private
final
List
<
String
>
threadNames
;
LazyTestBean
(
List
<
String
>
threadNames
)
{
this
.
threadNames
=
threadNames
;
}
@Scheduled
(
fixedRate
=
2000
)
void
accumulate
()
{
this
.
threadNames
.
add
(
Thread
.
currentThread
().
getName
());
}
}
static
class
TestTaskScheduler
extends
ThreadPoolTaskScheduler
{
static
class
TestTaskScheduler
extends
ThreadPoolTaskScheduler
{
TestTaskScheduler
()
{
TestTaskScheduler
()
{
...
...
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